mirror of
https://github.com/processone/ejabberd
synced 2025-10-03 17:59:31 +02:00
gen_mod: Add support to prepare module stopping before actually stopping any module
Follows the reasoning of application:prep_stop, but applied to gen_mod: https://www.erlang.org/docs/28/apps/kernel/application.html#c:prep_stop/1
This commit is contained in:
parent
4a51bf90ab
commit
3d89c9199c
2 changed files with 39 additions and 2 deletions
|
@ -109,6 +109,7 @@ prep_stop(State) ->
|
||||||
ejabberd_service:stop(),
|
ejabberd_service:stop(),
|
||||||
ejabberd_s2s:stop(),
|
ejabberd_s2s:stop(),
|
||||||
ejabberd_system_monitor:stop(),
|
ejabberd_system_monitor:stop(),
|
||||||
|
gen_mod:prep_stop(),
|
||||||
gen_mod:stop(),
|
gen_mod:stop(),
|
||||||
State.
|
State.
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
-author('alexey@process-one.net').
|
-author('alexey@process-one.net').
|
||||||
|
|
||||||
-export([init/1, start_link/0, start_child/3, start_child/4,
|
-export([init/1, start_link/0, start_child/3, start_child/4,
|
||||||
stop_child/1, stop_child/2, stop/0, config_reloaded/0]).
|
stop_child/1, stop_child/2, prep_stop/0, stop/0, config_reloaded/0]).
|
||||||
-export([start_module/2, stop_module/2, stop_module_keep_config/2,
|
-export([start_module/2, stop_module/2, stop_module_keep_config/2,
|
||||||
get_opt/2, set_opt/3, get_opt_hosts/1, is_equal_opt/3,
|
get_opt/2, set_opt/3, get_opt_hosts/1, is_equal_opt/3,
|
||||||
get_module_opt/3, get_module_opts/2, get_module_opt_hosts/2,
|
get_module_opt/3, get_module_opts/2, get_module_opt_hosts/2,
|
||||||
|
@ -76,6 +76,7 @@
|
||||||
-callback start(binary(), opts()) ->
|
-callback start(binary(), opts()) ->
|
||||||
ok | {ok, pid()} |
|
ok | {ok, pid()} |
|
||||||
{ok, [registration()]} | {error, term()}.
|
{ok, [registration()]} | {error, term()}.
|
||||||
|
-callback prep_stop(binary()) -> any().
|
||||||
-callback stop(binary()) -> any().
|
-callback stop(binary()) -> any().
|
||||||
-callback reload(binary(), opts(), opts()) -> ok | {ok, pid()} | {error, term()}.
|
-callback reload(binary(), opts(), opts()) -> ok | {ok, pid()} | {error, term()}.
|
||||||
-callback mod_opt_type(atom()) -> econf:validator().
|
-callback mod_opt_type(atom()) -> econf:validator().
|
||||||
|
@ -86,7 +87,7 @@
|
||||||
example => [string()] | [{binary(), [string()]}]}.
|
example => [string()] | [{binary(), [string()]}]}.
|
||||||
-callback depends(binary(), opts()) -> [{module(), hard | soft}].
|
-callback depends(binary(), opts()) -> [{module(), hard | soft}].
|
||||||
|
|
||||||
-optional_callbacks([mod_opt_type/1, reload/3]).
|
-optional_callbacks([mod_opt_type/1, reload/3, prep_stop/1]).
|
||||||
|
|
||||||
-export_type([opts/0]).
|
-export_type([opts/0]).
|
||||||
-export_type([db_type/0]).
|
-export_type([db_type/0]).
|
||||||
|
@ -114,6 +115,10 @@ init([]) ->
|
||||||
{read_concurrency, true}]),
|
{read_concurrency, true}]),
|
||||||
{ok, {{one_for_one, 10, 1}, []}}.
|
{ok, {{one_for_one, 10, 1}, []}}.
|
||||||
|
|
||||||
|
-spec prep_stop() -> ok.
|
||||||
|
prep_stop() ->
|
||||||
|
prep_stop_modules().
|
||||||
|
|
||||||
-spec stop() -> ok.
|
-spec stop() -> ok.
|
||||||
stop() ->
|
stop() ->
|
||||||
ejabberd_hooks:delete(config_reloaded, ?MODULE, config_reloaded, 60),
|
ejabberd_hooks:delete(config_reloaded, ?MODULE, config_reloaded, 60),
|
||||||
|
@ -301,6 +306,21 @@ is_app_running(AppName) ->
|
||||||
lists:keymember(AppName, 1,
|
lists:keymember(AppName, 1,
|
||||||
application:which_applications(Timeout)).
|
application:which_applications(Timeout)).
|
||||||
|
|
||||||
|
-spec prep_stop_modules() -> ok.
|
||||||
|
prep_stop_modules() ->
|
||||||
|
lists:foreach(
|
||||||
|
fun(Host) ->
|
||||||
|
prep_stop_modules(Host)
|
||||||
|
end, ejabberd_option:hosts()).
|
||||||
|
|
||||||
|
-spec prep_stop_modules(binary()) -> ok.
|
||||||
|
prep_stop_modules(Host) ->
|
||||||
|
Modules = lists:reverse(loaded_modules_with_opts(Host)),
|
||||||
|
lists:foreach(
|
||||||
|
fun({Module, _Args}) ->
|
||||||
|
prep_stop_module_keep_config(Host, Module)
|
||||||
|
end, Modules).
|
||||||
|
|
||||||
-spec stop_modules() -> ok.
|
-spec stop_modules() -> ok.
|
||||||
stop_modules() ->
|
stop_modules() ->
|
||||||
lists:foreach(
|
lists:foreach(
|
||||||
|
@ -320,6 +340,22 @@ stop_modules(Host) ->
|
||||||
stop_module(Host, Module) ->
|
stop_module(Host, Module) ->
|
||||||
stop_module_keep_config(Host, Module).
|
stop_module_keep_config(Host, Module).
|
||||||
|
|
||||||
|
-spec prep_stop_module_keep_config(binary(), atom()) -> error | ok.
|
||||||
|
prep_stop_module_keep_config(Host, Module) ->
|
||||||
|
?DEBUG("Preparing to stop ~ts at ~ts", [Module, Host]),
|
||||||
|
try Module:prep_stop(Host) of
|
||||||
|
_ ->
|
||||||
|
ok
|
||||||
|
catch ?EX_RULE(error, undef, _St) ->
|
||||||
|
ok;
|
||||||
|
?EX_RULE(Class, Reason, St) ->
|
||||||
|
StackTrace = ?EX_STACK(St),
|
||||||
|
?ERROR_MSG("Failed to prepare stop module ~ts at ~ts:~n** ~ts",
|
||||||
|
[Module, Host,
|
||||||
|
misc:format_exception(2, Class, Reason, StackTrace)]),
|
||||||
|
error
|
||||||
|
end.
|
||||||
|
|
||||||
-spec stop_module_keep_config(binary(), atom()) -> error | ok.
|
-spec stop_module_keep_config(binary(), atom()) -> error | ok.
|
||||||
stop_module_keep_config(Host, Module) ->
|
stop_module_keep_config(Host, Module) ->
|
||||||
?DEBUG("Stopping ~ts at ~ts", [Module, Host]),
|
?DEBUG("Stopping ~ts at ~ts", [Module, Host]),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue