diff options
Diffstat (limited to 'src/mod_stream_mgmt.erl')
-rw-r--r-- | src/mod_stream_mgmt.erl | 54 |
1 files changed, 42 insertions, 12 deletions
diff --git a/src/mod_stream_mgmt.erl b/src/mod_stream_mgmt.erl index 127eea3e8..068550906 100644 --- a/src/mod_stream_mgmt.erl +++ b/src/mod_stream_mgmt.erl @@ -33,6 +33,8 @@ c2s_unbinded_packet/2, c2s_closed/2, c2s_terminated/2, c2s_handle_send/3, c2s_handle_info/2, c2s_handle_call/3, c2s_handle_recv/3]). +%% adjust pending session timeout +-export([get_resume_timeout/1, set_resume_timeout/2]). -include("xmpp.hrl"). -include("logger.hrl"). @@ -235,8 +237,9 @@ c2s_handle_info(#{mgmt_ack_timer := TRef, jid := JID, mod := Mod} = State, [jid:encode(JID)]), State1 = Mod:close(State), {stop, transition_to_pending(State1)}; -c2s_handle_info(#{mgmt_state := pending, jid := JID, mod := Mod} = State, - {timeout, _, pending_timeout}) -> +c2s_handle_info(#{mgmt_state := pending, + mgmt_pending_timer := TRef, jid := JID, mod := Mod} = State, + {timeout, TRef, pending_timeout}) -> ?DEBUG("Timed out waiting for resumption of stream for ~s", [jid:encode(JID)]), Mod:stop(State#{mgmt_state => timeout}); @@ -283,6 +286,20 @@ c2s_terminated(State, _Reason) -> State. %%%=================================================================== +%%% Adjust pending session timeout +%%%=================================================================== +-spec get_resume_timeout(state()) -> non_neg_integer(). +get_resume_timeout(#{mgmt_timeout := Timeout}) -> + Timeout. + +-spec set_resume_timeout(state(), non_neg_integer()) -> state(). +set_resume_timeout(#{mgmt_timeout := Timeout} = State, Timeout) -> + State; +set_resume_timeout(State, Timeout) -> + State1 = restart_pending_timer(State, Timeout), + State1#{mgmt_timeout => Timeout}. + +%%%=================================================================== %%% Internal functions %%%=================================================================== -spec negotiate_stream_mgmt(xmpp_element(), state()) -> state(). @@ -408,8 +425,8 @@ transition_to_pending(#{mgmt_state := active, jid := JID, lserver := LServer, mgmt_timeout := Timeout} = State) -> State1 = cancel_ack_timer(State), ?INFO_MSG("Waiting for resumption of stream for ~s", [jid:encode(JID)]), - erlang:start_timer(timer:seconds(Timeout), self(), pending_timeout), - State2 = State1#{mgmt_state => pending}, + TRef = erlang:start_timer(timer:seconds(Timeout), self(), pending_timeout), + State2 = State1#{mgmt_state => pending, mgmt_pending_timer => TRef}, ejabberd_hooks:run_fold(c2s_session_pending, LServer, State2, []); transition_to_pending(State) -> State. @@ -648,20 +665,33 @@ add_resent_delay_info(_State, El, _Time) -> send(#{mod := Mod} = State, Pkt) -> Mod:send(State, Pkt). +-spec restart_pending_timer(state(), non_neg_integer()) -> state(). +restart_pending_timer(#{mgmt_pending_timer := TRef} = State, NewTimeout) -> + cancel_timer(TRef), + NewTRef = erlang:start_timer(timer:seconds(NewTimeout), self(), + pending_timeout), + State#{mgmt_pending_timer => NewTRef}; +restart_pending_timer(State, _NewTimeout) -> + State. + -spec cancel_ack_timer(state()) -> state(). cancel_ack_timer(#{mgmt_ack_timer := TRef} = State) -> - case erlang:cancel_timer(TRef) of - false -> - receive {timeout, TRef, _} -> ok - after 0 -> ok - end; - _ -> - ok - end, + cancel_timer(TRef), maps:remove(mgmt_ack_timer, State); cancel_ack_timer(State) -> State. +-spec cancel_timer(reference()) -> ok. +cancel_timer(TRef) -> + case erlang:cancel_timer(TRef) of + false -> + receive {timeout, TRef, _} -> ok + after 0 -> ok + end; + _ -> + ok + end. + -spec bounce_message_queue() -> ok. bounce_message_queue() -> receive {route, Pkt} -> |