aboutsummaryrefslogtreecommitdiff
path: root/src/mod_ping.erl
diff options
context:
space:
mode:
authorEvgeniy Khramtsov <ekhramtsov@process-one.net>2017-02-22 19:46:47 +0300
committerEvgeniy Khramtsov <ekhramtsov@process-one.net>2017-02-22 19:46:47 +0300
commit3c4057ff553928d4e4ab40e410dbc6a478dd8206 (patch)
treea0272f84a1221db928cfd4c9f44d9bed6e196bc8 /src/mod_ping.erl
parentMake sure all hooks are called with proper host (diff)
Reload modules when reloading configuration file
Diffstat (limited to 'src/mod_ping.erl')
-rw-r--r--src/mod_ping.erl122
1 files changed, 78 insertions, 44 deletions
diff --git a/src/mod_ping.erl b/src/mod_ping.erl
index aa048e36e..0e2ccb9fa 100644
--- a/src/mod_ping.erl
+++ b/src/mod_ping.erl
@@ -48,7 +48,7 @@
-export([start_ping/2, stop_ping/2]).
%% gen_mod callbacks
--export([start/2, stop/1]).
+-export([start/2, stop/1, reload/3]).
%% gen_server callbacks
-export([init/1, terminate/2, handle_call/3,
@@ -87,64 +87,49 @@ start(Host, Opts) ->
stop(Host) ->
gen_mod:stop_child(?MODULE, Host).
+reload(Host, NewOpts, OldOpts) ->
+ Proc = gen_mod:get_module_proc(Host, ?MODULE),
+ gen_server:cast(Proc, {reload, Host, NewOpts, OldOpts}).
+
%%====================================================================
%% gen_server callbacks
%%====================================================================
init([Host, Opts]) ->
process_flag(trap_exit, true),
- SendPings = gen_mod:get_opt(send_pings, Opts,
- fun(B) when is_boolean(B) -> B end,
- ?DEFAULT_SEND_PINGS),
- PingInterval = gen_mod:get_opt(ping_interval, Opts,
- fun(I) when is_integer(I), I>0 -> I end,
- ?DEFAULT_PING_INTERVAL),
- PingAckTimeout = gen_mod:get_opt(ping_ack_timeout, Opts,
- fun(I) when is_integer(I), I>0 -> I * 1000 end,
- undefined),
- TimeoutAction = gen_mod:get_opt(timeout_action, Opts,
- fun(none) -> none;
- (kill) -> kill
- end, none),
+ State = init_state(Host, Opts),
IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1,
no_queue),
- gen_iq_handler:add_iq_handler(ejabberd_sm, Host,
- ?NS_PING, ?MODULE, iq_ping, IQDisc),
- gen_iq_handler:add_iq_handler(ejabberd_local, Host,
- ?NS_PING, ?MODULE, iq_ping, IQDisc),
- case SendPings of
- true ->
- ejabberd_hooks:add(sm_register_connection_hook, Host,
- ?MODULE, user_online, 100),
- ejabberd_hooks:add(sm_remove_connection_hook, Host,
- ?MODULE, user_offline, 100),
- ejabberd_hooks:add(user_send_packet, Host, ?MODULE,
- user_send, 100);
- _ -> ok
+ register_iq_handlers(Host, IQDisc),
+ case State#state.send_pings of
+ true -> register_hooks(Host);
+ false -> ok
end,
- {ok,
- #state{host = Host, send_pings = SendPings,
- ping_interval = PingInterval,
- timeout_action = TimeoutAction,
- ping_ack_timeout = PingAckTimeout,
- timers = maps:new()}}.
+ {ok, State}.
terminate(_Reason, #state{host = Host}) ->
- ejabberd_hooks:delete(sm_remove_connection_hook, Host,
- ?MODULE, user_offline, 100),
- ejabberd_hooks:delete(sm_register_connection_hook, Host,
- ?MODULE, user_online, 100),
- ejabberd_hooks:delete(user_send_packet, Host, ?MODULE,
- user_send, 100),
- gen_iq_handler:remove_iq_handler(ejabberd_local, Host,
- ?NS_PING),
- gen_iq_handler:remove_iq_handler(ejabberd_sm, Host,
- ?NS_PING).
+ unregister_hooks(Host),
+ unregister_iq_handlers(Host).
handle_call(stop, _From, State) ->
{stop, normal, ok, State};
handle_call(_Req, _From, State) ->
{reply, {error, badarg}, State}.
+handle_cast({reload, Host, NewOpts, OldOpts},
+ #state{timers = Timers} = OldState) ->
+ case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts,
+ fun gen_iq_handler:check_type/1,
+ one_queue) of
+ {false, IQDisc, _} -> register_iq_handlers(Host, IQDisc);
+ true -> ok
+ end,
+ NewState = init_state(Host, NewOpts),
+ case {NewState#state.send_pings, OldState#state.send_pings} of
+ {true, false} -> register_hooks(Host);
+ {false, true} -> unregister_hooks(Host);
+ _ -> ok
+ end,
+ {noreply, NewState#state{timers = Timers}};
handle_cast({start_ping, JID}, State) ->
Timers = add_timer(JID, State#state.ping_interval,
State#state.timers),
@@ -169,7 +154,9 @@ handle_cast({iq_pong, JID, timeout}, State) ->
_ -> ok
end,
{noreply, State#state{timers = Timers}};
-handle_cast(_Msg, State) -> {noreply, State}.
+handle_cast(Msg, State) ->
+ ?WARNING_MSG("unexpected cast: ~p", [Msg]),
+ {noreply, State}.
handle_info({timeout, _TRef, {ping, JID}}, State) ->
From = jid:make(State#state.host),
@@ -212,6 +199,53 @@ user_send({Packet, #{jid := JID} = C2SState}) ->
%%====================================================================
%% Internal functions
%%====================================================================
+init_state(Host, Opts) ->
+ SendPings = gen_mod:get_opt(send_pings, Opts,
+ fun(B) when is_boolean(B) -> B end,
+ ?DEFAULT_SEND_PINGS),
+ PingInterval = gen_mod:get_opt(ping_interval, Opts,
+ fun(I) when is_integer(I), I>0 -> I end,
+ ?DEFAULT_PING_INTERVAL),
+ PingAckTimeout = gen_mod:get_opt(ping_ack_timeout, Opts,
+ fun(I) when is_integer(I), I>0 -> I * 1000 end,
+ undefined),
+ TimeoutAction = gen_mod:get_opt(timeout_action, Opts,
+ fun(none) -> none;
+ (kill) -> kill
+ end, none),
+ #state{host = Host,
+ send_pings = SendPings,
+ ping_interval = PingInterval,
+ timeout_action = TimeoutAction,
+ ping_ack_timeout = PingAckTimeout,
+ timers = maps:new()}.
+
+register_hooks(Host) ->
+ ejabberd_hooks:add(sm_register_connection_hook, Host,
+ ?MODULE, user_online, 100),
+ ejabberd_hooks:add(sm_remove_connection_hook, Host,
+ ?MODULE, user_offline, 100),
+ ejabberd_hooks:add(user_send_packet, Host, ?MODULE,
+ user_send, 100).
+
+unregister_hooks(Host) ->
+ ejabberd_hooks:delete(sm_remove_connection_hook, Host,
+ ?MODULE, user_offline, 100),
+ ejabberd_hooks:delete(sm_register_connection_hook, Host,
+ ?MODULE, user_online, 100),
+ ejabberd_hooks:delete(user_send_packet, Host, ?MODULE,
+ user_send, 100).
+
+register_iq_handlers(Host, IQDisc) ->
+ gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_PING,
+ ?MODULE, iq_ping, IQDisc),
+ gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_PING,
+ ?MODULE, iq_ping, IQDisc).
+
+unregister_iq_handlers(Host) ->
+ gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_PING),
+ gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_PING).
+
-spec add_timer(jid(), non_neg_integer(), map()) -> map().
add_timer(JID, Interval, Timers) ->
LJID = jid:tolower(JID),