summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Watson <tim@rabbitmq.com>2012-05-04 13:31:25 +0100
committerTim Watson <tim@rabbitmq.com>2012-05-04 13:31:25 +0100
commit7ac5a4750af268ecdd71168854aad726695ce9a2 (patch)
treea505fe7748de3216866563134d03e7447c16f5ac
parented2e74690c0a02567a48b1eaf0ef41b0d87f6e97 (diff)
downloadrabbitmq-server-7ac5a4750af268ecdd71168854aad726695ce9a2.tar.gz
ensure that all dependent applications are stopped when shutting down the broker without halting the emulator
-rw-r--r--src/rabbit.erl10
-rw-r--r--src/rabbit_misc.erl19
2 files changed, 21 insertions, 8 deletions
diff --git a/src/rabbit.erl b/src/rabbit.erl
index 588cc390..6425730c 100644
--- a/src/rabbit.erl
+++ b/src/rabbit.erl
@@ -298,7 +298,7 @@ prepare() ->
start() ->
start_it(fun() ->
ok = prepare(),
- ok = rabbit_misc:start_applications(application_load_order()),
+ ok = rabbit_misc:start_applications(app_startup_order()),
ok = print_plugin_info(rabbit_plugins:active_plugins())
end).
@@ -327,7 +327,7 @@ start_it(StartFun) ->
stop() ->
rabbit_log:info("Stopping Rabbit~n"),
- ok = rabbit_misc:stop_applications(application_load_order()).
+ ok = rabbit_misc:stop_applications(app_shutdown_order()).
stop_and_halt() ->
try
@@ -414,10 +414,14 @@ stop(_State) ->
%%---------------------------------------------------------------------------
%% application life cycle
-application_load_order() ->
+app_startup_order() ->
ok = rabbit_misc:load_applications(?APPS),
rabbit_misc:calculate_app_dependency_ordering(?APPS).
+app_shutdown_order() ->
+ Apps = ?APPS ++ rabbit_plugins:active_plugins(),
+ rabbit_misc:calculate_app_dependency_ordering(Apps, true).
+
%%---------------------------------------------------------------------------
%% boot step logic
diff --git a/src/rabbit_misc.erl b/src/rabbit_misc.erl
index 87865ebc..6371c24c 100644
--- a/src/rabbit_misc.erl
+++ b/src/rabbit_misc.erl
@@ -42,8 +42,9 @@
-export([dirty_read_all/1, dirty_foreach_key/2, dirty_dump_log/1]).
-export([format/2, format_many/1, format_stderr/2]).
-export([with_local_io/1, local_info_msg/2]).
--export([calculate_app_dependency_ordering/1, load_applications/1,
- start_applications/1, stop_applications/1]).
+-export([calculate_app_dependency_ordering/1,
+ calculate_app_dependency_ordering/2]).
+-export([load_applications/1, start_applications/1, stop_applications/1]).
-export([unfold/2, ceil/1, queue_fold/3]).
-export([sort_field_table/1]).
-export([pid_to_string/1, string_to_pid/1]).
@@ -171,7 +172,9 @@
-spec(local_info_msg/2 :: (string(), [any()]) -> 'ok').
-spec(start_applications/1 :: ([atom()]) -> 'ok').
-spec(load_applications/1 :: ([atom()]) -> 'ok').
--spec(calculate_app_dependency_ordering/1 :: ([atom()]) -> 'ok').
+-spec(calculate_app_dependency_ordering/1 :: ([atom()]) -> [digraph:vertex()]).
+-spec(calculate_app_dependency_ordering/2 :: ([atom()],
+ boolean()) -> [digraph:vertex()]).
-spec(stop_applications/1 :: ([atom()]) -> 'ok').
-spec(unfold/2 :: (fun ((A) -> ({'true', B, A} | 'false')), A) -> {[B], A}).
-spec(ceil/1 :: (number()) -> integer()).
@@ -670,14 +673,20 @@ stop_applications(Apps) ->
Apps).
calculate_app_dependency_ordering(RootApps) ->
+ calculate_app_dependency_ordering(RootApps, false).
+
+calculate_app_dependency_ordering(RootApps, StripUnreachable) ->
{ok, G} = build_acyclic_graph(
fun (App, _Deps) -> [{App, App}] end,
fun (App, Deps) -> [{Dep, App} || Dep <- Deps] end,
[{App, app_dependencies(App)} ||
{App, _Desc, _Vsn} <- application:loaded_applications()]),
try
- true = digraph:del_vertices(G, digraph:vertices(G) --
- digraph_utils:reachable(RootApps, G)),
+ case StripUnreachable of
+ true -> digraph:del_vertices(G, digraph:vertices(G) --
+ digraph_utils:reachable(RootApps, G));
+ false -> ok
+ end,
digraph_utils:topsort(G)
after
true = digraph:delete(G)