diff options
author | Michael Klishin <michael@clojurewerkz.org> | 2020-01-30 19:12:12 +0300 |
---|---|---|
committer | Michael Klishin <michael@clojurewerkz.org> | 2020-01-30 19:12:12 +0300 |
commit | 6a4d2721d06b8c70a36e29e6c51bbef6608def55 (patch) | |
tree | def023bec87e22c4c542df1dfd76d28f01c94cf4 | |
parent | d621ec907a4b7f33e85e4bc61f10d1c6e1ef0601 (diff) | |
download | rabbitmq-server-git-6a4d2721d06b8c70a36e29e6c51bbef6608def55.tar.gz |
Override OTP handlers to gracefully shut down on SIGTERM, SIGQUIT
otherwise the default handler will terminate the runtime.
Closes #2222.
Pair: @vanlightly.
-rw-r--r-- | src/rabbit.erl | 6 | ||||
-rw-r--r-- | src/rabbit_os_signal_handler.erl | 57 |
2 files changed, 63 insertions, 0 deletions
diff --git a/src/rabbit.erl b/src/rabbit.erl index 35ffc6ea16..0bf6d47700 100644 --- a/src/rabbit.erl +++ b/src/rabbit.erl @@ -235,6 +235,12 @@ {requires, pre_flight} ]}). +-rabbit_boot_step({os_signal_handler, + [{description, "registers an OS signal handler"}, + {mfa, {rabbit_sup, start_restartable_child, + [rabbit_os_signal_handler]}}, + {requires, pre_flight}]}). + -rabbit_boot_step({direct_client, [{description, "direct client"}, {mfa, {rabbit_direct, boot, []}}, diff --git a/src/rabbit_os_signal_handler.erl b/src/rabbit_os_signal_handler.erl new file mode 100644 index 0000000000..df1a421f09 --- /dev/null +++ b/src/rabbit_os_signal_handler.erl @@ -0,0 +1,57 @@ +-module(rabbit_os_signal_handler). + +-behaviour(gen_event). + +-export([start_link/0, init/1, + handle_event/2, handle_call/2, handle_info/2, + terminate/2]). + +%% +%% API +%% + +start_link() -> + rabbit_log:info("Swapping OS signal event handler (erl_signal_server) for our own"), + %% delete any previous incarnations, otherwise we would be accumulating + %% handlers + _ = gen_event:delete_handler(erl_signal_server, ?MODULE, []), + %% swap the standard OTP signal handler if there is one + ok = gen_event:swap_sup_handler( + erl_signal_server, + %% what to swap + {erl_signal_handler, []}, + %% new event handler + {?MODULE, []}), + gen_event:start_link({local, ?MODULE}). + +init(_) -> + {ok, #{}}. + +handle_event(sigterm, State) -> + rabbit_log:info("Received a SIGTERM, will shut down gracefully"), + rabbit:stop_and_halt(), + {ok, State}; +handle_event(sigquit, State) -> + rabbit_log:info("Received a SIGQUIT, will shut down gracefully"), + rabbit:stop_and_halt(), + {ok, State}; +handle_event(sigusr1, State) -> + rabbit_log:info("Received a SIGUSR1, ignoring it"), + {ok, State}; +%% note: SIGHUP can/will be handled by shells and process managers +handle_event(sighup, State) -> + rabbit_log:info("Received a SIGHUP, ignoring it"), + {ok, State}; +handle_event(Msg, S) -> + %% delegate all unknown events to the default OTP signal handler + erl_signal_handler:handle_event(Msg, S), + {ok, S}. + +handle_info(_, State) -> + {ok, State}. + +handle_call(_Request, State) -> + {ok, ok, State}. + +terminate(_Args, _State) -> + ok. |