diff options
author | Tim Watson <watson.timothy@gmail.com> | 2013-11-20 12:13:05 +0000 |
---|---|---|
committer | Tim Watson <watson.timothy@gmail.com> | 2013-11-20 12:13:05 +0000 |
commit | bc371b7de17216b213ac3ef3638b42d31fcc7b79 (patch) | |
tree | c8ccb6a04efc835a5d59467449ca4b87be2598d6 /src/app_utils.erl | |
parent | 3f557dc14fc766f50e371a469aa092767acb98e3 (diff) | |
download | rabbitmq-server-git-bc371b7de17216b213ac3ef3638b42d31fcc7b79.tar.gz |
Various boot procedure improvements
We ensure that all dependent applications are stopped, but also that
dependencies shared by multiple applications (e.g., amqp_client) are
not.
Diffstat (limited to 'src/app_utils.erl')
-rw-r--r-- | src/app_utils.erl | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/src/app_utils.erl b/src/app_utils.erl index 1231ea586a..d08dfe6a5a 100644 --- a/src/app_utils.erl +++ b/src/app_utils.erl @@ -18,6 +18,7 @@ -export([load_applications/1, start_applications/1, start_applications/2, stop_applications/1, stop_applications/2, app_dependency_order/2, running_applications/0, wait_for_applications/1, app_dependencies/1]). +-export([direct_dependencies/1]). -ifdef(use_specs). @@ -31,6 +32,7 @@ -spec wait_for_applications([atom()]) -> 'ok'. -spec app_dependency_order([atom()], boolean()) -> [digraph:vertex()]. -spec app_dependencies(atom()) -> [atom()]. +-spec direct_dependencies(atom()) -> [atom()]. -endif. @@ -75,6 +77,40 @@ stop_applications(Apps, ErrorHandler) -> wait_for_applications(Apps) -> [wait_for_application(App) || App <- Apps], ok. +direct_dependencies(Root) -> + G = digraph:new(), + Loaded = application:loaded_applications(), + try + [begin + case digraph:vertex(G, App) of + false -> digraph:add_vertex(G, App, App); + _ -> ok = throw({graph_error, {vertex, duplicate, App}}) + end + end || {App, _, _} <- Loaded], + [digraph:add_edge(G, App, Dep) || + {App, Deps} <- [{App, app_dependencies(App)} || + {App, _Desc, _Vsn} <- Loaded], + Dep <- Deps], + Deps = lists:foldl( + fun(E, Acc) -> + {_, _InVertex, OutVertex, _Label} = digraph:edge(G, E), + case is_reachable(G, OutVertex, Root) of + [] -> sets:add_element(OutVertex, Acc); + _ -> Acc + end + end, + sets:from_list([Root]), + digraph:out_edges(G, Root)), + sets:to_list(sets:del_element(rabbit, Deps)) + catch {graph_error, Reason} -> + {error, Reason} + after + true = digraph:delete(G) + end. + +is_reachable(G, OutVertex, Root) -> + digraph_utils:reaching_neighbours([OutVertex], G) -- [Root]. + app_dependency_order(RootApps, StripUnreachable) -> {ok, G} = rabbit_misc:build_acyclic_graph( fun (App, _Deps) -> [{App, App}] end, |