diff --git a/src/emqttd_app.erl b/src/emqttd_app.erl index 06113ea08..b35614cd7 100644 --- a/src/emqttd_app.erl +++ b/src/emqttd_app.erl @@ -149,23 +149,41 @@ register_acl_mod() -> %%-------------------------------------------------------------------- start_autocluster() -> - ekka:callback(prepare, fun emqttd:shutdown/1), - ekka:callback(reboot, fun emqttd:reboot/0), - Fun = fun() -> ekka_autocluster:start(fun after_autocluster/0) end, - run_outside_application(5000, Fun). + case application:get_env(?APP, autocluster_lock) of + undefined -> + application:set_env(?APP, autocluster_lock, true), + ekka:callback(prepare, fun emqttd:shutdown/1), + ekka:callback(reboot, fun emqttd:reboot/0), + run_outside_application({ekka_autocluster, start, [fun after_autocluster/0]}); + {ok, _Lock} -> + ignore + end. after_autocluster() -> emqttd_plugins:init(), emqttd_plugins:load(), start_listeners(). -run_outside_application(Delay, Callback) -> +run_outside_application({M, F, Args}) -> spawn(fun() -> group_leader(whereis(init), self()), - timer:sleep(Delay), - Callback() + wait_app_ready(5), + try erlang:apply(M, F, Args) + catch + _:Error -> lager:error("Autocluster exception: ~p", [Error]) + end, + application:unset_env(?APP, autocluster_lock) end). +wait_app_ready(0) -> + timeout; +wait_app_ready(Retries) -> + case lists:keymember(?APP, 1, application:which_applications()) of + true -> ok; + false -> timer:sleep(1000), + wait_app_ready(Retries - 1) + end. + %%-------------------------------------------------------------------- %% Start Listeners %%--------------------------------------------------------------------