]> granicus.if.org Git - ejabberd/commitdiff
Avoid late arrival of get_disco_item response
authorEvgeny Khramtsov <ekhramtsov@process-one.net>
Sat, 11 May 2019 16:27:56 +0000 (19:27 +0300)
committerEvgeny Khramtsov <ekhramtsov@process-one.net>
Sat, 11 May 2019 16:27:56 +0000 (19:27 +0300)
src/mod_muc.erl
src/mod_muc_room.erl

index edc570eedd563d76a3892f561a74948ebde4248b..a3447b2811e4e18c2385179349beef41709de1ed 100644 (file)
@@ -740,17 +740,21 @@ iq_disco_items(_ServerHost, _Host, _From, Lang, _MaxRoomsDiscoItems, _Node, _RSM
 -spec get_room_disco_item({binary(), binary(), pid()},
                          term()) -> {ok, disco_item()} |
                                     {error, timeout | notfound}.
-get_room_disco_item({Name, Host, Pid}, Query) ->
-           RoomJID = jid:make(Name, Host),
-           try p1_fsm:sync_send_all_state_event(Pid, Query, 100) of
-               {item, Desc} ->
-                   {ok, #disco_item{jid = RoomJID, name = Desc}};
-               false ->
-                   {error, notfound}
-           catch _:{timeout, {p1_fsm, _, _}} ->
-                   {error, timeout};
-                 _:{_, {p1_fsm, _, _}} ->
-                   {error, notfound}
+get_room_disco_item({Name, Host, Pid},
+                   {get_disco_item, Filter, JID, Lang}) ->
+    RoomJID = jid:make(Name, Host),
+    Timeout = 100,
+    Time = erlang:monotonic_time(millisecond),
+    Query1 = {get_disco_item, Filter, JID, Lang, Time+Timeout},
+    try p1_fsm:sync_send_all_state_event(Pid, Query1, Timeout) of
+       {item, Desc} ->
+           {ok, #disco_item{jid = RoomJID, name = Desc}};
+       false ->
+           {error, notfound}
+    catch _:{timeout, {p1_fsm, _, _}} ->
+           {error, timeout};
+         _:{_, {p1_fsm, _, _}} ->
+           {error, notfound}
     end.
 
 -spec get_subscribed_rooms(binary(), jid()) -> {ok, [{jid(), [binary()]}]} | {error, any()}.
index 94c4301972cf67ad2cab2a59232a0e53f0f3bba4..2d386512020491dcffd0b273a4f2e20de32563d0 100644 (file)
@@ -512,7 +512,7 @@ handle_event({set_affiliations, Affiliations},
 handle_event(_Event, StateName, StateData) ->
     {next_state, StateName, StateData}.
 
-handle_sync_event({get_disco_item, Filter, JID, Lang}, _From, StateName, StateData) ->
+handle_sync_event({get_disco_item, Filter, JID, Lang, Time}, _From, StateName, StateData) ->
     Len = maps:size(StateData#state.nicks),
     Reply = case (Filter == all) or (Filter == Len) or ((Filter /= 0) and (Len /= 0)) of
        true ->
@@ -521,10 +521,17 @@ handle_sync_event({get_disco_item, Filter, JID, Lang}, _From, StateName, StateDa
        false ->
            false
     end,
-    {reply, Reply, StateName, StateData};
-%% This clause is only for backwards compatibility
+    CurrentTime = erlang:monotonic_time(millisecond),
+    if CurrentTime < Time ->
+           {reply, Reply, StateName, StateData};
+       true ->
+           {next_state, StateName, StateData}
+    end;
+%% These two clauses are only for backward compatibility with nodes running old code
 handle_sync_event({get_disco_item, JID, Lang}, From, StateName, StateData) ->
     handle_sync_event({get_disco_item, any, JID, Lang}, From, StateName, StateData);
+handle_sync_event({get_disco_item, Filter, JID, Lang}, From, StateName, StateData) ->
+    handle_sync_event({get_disco_item, Filter, JID, Lang, infinity}, From, StateName, StateData);
 handle_sync_event(get_config, _From, StateName,
                  StateData) ->
     {reply, {ok, StateData#state.config}, StateName,