diff options
| author | Tim Watson <tim.watson@gmail.com> | 2012-05-09 10:57:36 +0100 |
|---|---|---|
| committer | Tim Watson <tim.watson@gmail.com> | 2012-05-09 10:57:36 +0100 |
| commit | 244c1ddf76425366f42395c8231bd4e97e6dbd4b (patch) | |
| tree | 31c70fc29c212512709892f40ad362010f22b014 /src | |
| parent | 764f688edb74e2cc9bbf59ef49e8b47a4a75452d (diff) | |
| download | rabbitmq-server-git-244c1ddf76425366f42395c8231bd4e97e6dbd4b.tar.gz | |
migrate application handling code to app_utils
Diffstat (limited to 'src')
| -rw-r--r-- | src/app_utils.erl | 109 | ||||
| -rw-r--r-- | src/rabbit.erl | 16 | ||||
| -rw-r--r-- | src/rabbit_misc.erl | 86 | ||||
| -rw-r--r-- | src/rabbit_networking.erl | 2 |
4 files changed, 118 insertions, 95 deletions
diff --git a/src/app_utils.erl b/src/app_utils.erl new file mode 100644 index 0000000000..dfbf710661 --- /dev/null +++ b/src/app_utils.erl @@ -0,0 +1,109 @@ +%% The contents of this file are subject to the Mozilla Public License +%% Version 1.1 (the "License"); you may not use this file except in +%% compliance with the License. You may obtain a copy of the License +%% at http://www.mozilla.org/MPL/ +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and +%% limitations under the License. +%% +%% The Original Code is RabbitMQ. +%% +%% The Initial Developer of the Original Code is VMware, Inc. +%% Copyright (c) 2007-2012 VMware, Inc. All rights reserved. +%% +-module(app_utils). + +-export([load_applications/1, start_applications/1, + stop_applications/1, app_dependency_order/2]). + +-ifdef(use_specs). + +-spec start_applications([atom()]) -> 'ok'. +-spec load_applications([atom()]) -> 'ok'. +-spec stop_applications([atom()]) -> 'ok'. +-spec app_dependency_order([atom()], boolean()) -> [digraph:vertex()]. + +-endif. + +%%--------------------------------------------------------------------------- +%% Public API + +load_applications(Apps) -> + load_applications(queue:from_list(Apps), sets:new()), + ok. + +start_applications(Apps) -> + manage_applications(fun lists:foldl/3, + fun application:start/1, + fun application:stop/1, + already_started, + cannot_start_application, + Apps). + +stop_applications(Apps) -> + manage_applications(fun lists:foldr/3, + fun application:stop/1, + fun application:start/1, + not_started, + cannot_stop_application, + Apps). + +app_dependency_order(RootApps, StripUnreachable) -> + {ok, G} = rabbit_misc: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 + 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) + end. + +%%--------------------------------------------------------------------------- +%% Private API + +load_applications(Worklist, Loaded) -> + case queue:out(Worklist) of + {empty, _WorkList} -> + ok; + {{value, App}, Worklist1} -> + case sets:is_element(App, Loaded) of + true -> load_applications(Worklist1, Loaded); + false -> case application:load(App) of + ok -> ok; + {error, {already_loaded, App}} -> ok; + Error -> throw(Error) + end, + load_applications( + queue:join(Worklist1, + queue:from_list(app_dependencies(App))), + sets:add_element(App, Loaded)) + end + end. + +app_dependencies(App) -> + case application:get_key(App, applications) of + undefined -> []; + {ok, Lst} -> Lst + end. + +manage_applications(Iterate, Do, Undo, SkipError, ErrorTag, Apps) -> + Iterate(fun (App, Acc) -> + case Do(App) of + ok -> [App | Acc]; + {error, {SkipError, _}} -> Acc; + {error, Reason} -> + lists:foreach(Undo, Acc), + throw({error, {ErrorTag, App, Reason}}) + end + end, [], Apps), + ok. + diff --git a/src/rabbit.erl b/src/rabbit.erl index b7e640ffb2..ee0f82a12e 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(app_startup_order()), + ok = app_utils:start_applications(app_startup_order()), ok = print_plugin_info(rabbit_plugins:active_plugins()) end). @@ -310,10 +310,10 @@ boot() -> io:format("~nActivating RabbitMQ plugins ...~n"), - ok = rabbit_misc:load_applications(ToBeLoaded), + ok = app_utils:load_applications(ToBeLoaded), StartupApps = - rabbit_misc:calculate_app_dependency_ordering(ToBeLoaded), - ok = rabbit_misc:start_applications(StartupApps), + app_utils:app_dependency_order(ToBeLoaded, false), + ok = app_utils:start_applications(StartupApps), ok = print_plugin_info(Plugins) end). @@ -328,7 +328,7 @@ start_it(StartFun) -> stop() -> rabbit_log:info("Stopping Rabbit~n"), - ok = rabbit_misc:stop_applications(app_shutdown_order()). + ok = app_utils:stop_applications(app_shutdown_order()). stop_and_halt() -> try @@ -416,12 +416,12 @@ stop(_State) -> %% application life cycle app_startup_order() -> - ok = rabbit_misc:load_applications(?APPS), - rabbit_misc:calculate_app_dependency_ordering(?APPS). + ok = app_utils:load_applications(?APPS), + app_utils:app_dependency_order(?APPS, false). app_shutdown_order() -> Apps = ?APPS ++ rabbit_plugins:active_plugins(), - rabbit_misc:calculate_app_dependency_ordering(Apps, true). + app_utils:app_dependency_order(Apps, true). %%--------------------------------------------------------------------------- %% boot step logic diff --git a/src/rabbit_misc.erl b/src/rabbit_misc.erl index 6371c24c12..955d769cbb 100644 --- a/src/rabbit_misc.erl +++ b/src/rabbit_misc.erl @@ -42,9 +42,6 @@ -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, - 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]). @@ -170,12 +167,6 @@ -spec(format_stderr/2 :: (string(), [any()]) -> 'ok'). -spec(with_local_io/1 :: (fun (() -> A)) -> A). -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()]) -> [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()). -spec(queue_fold/3 :: (fun ((any(), B) -> B), B, queue()) -> B). @@ -615,83 +606,6 @@ with_local_io(Fun) -> local_info_msg(Format, Args) -> with_local_io(fun () -> error_logger:info_msg(Format, Args) end). -manage_applications(Iterate, Do, Undo, SkipError, ErrorTag, Apps) -> - Iterate(fun (App, Acc) -> - case Do(App) of - ok -> [App | Acc]; - {error, {SkipError, _}} -> Acc; - {error, Reason} -> - lists:foreach(Undo, Acc), - throw({error, {ErrorTag, App, Reason}}) - end - end, [], Apps), - ok. - -load_applications(Apps) -> - load_applications(queue:from_list(Apps), sets:new()), - ok. - -load_applications(Worklist, Loaded) -> - case queue:out(Worklist) of - {empty, _WorkList} -> - ok; - {{value, App}, Worklist1} -> - case sets:is_element(App, Loaded) of - true -> load_applications(Worklist1, Loaded); - false -> case application:load(App) of - ok -> ok; - {error, {already_loaded, App}} -> ok; - Error -> throw(Error) - end, - load_applications( - queue:join(Worklist1, - queue:from_list(app_dependencies(App))), - sets:add_element(App, Loaded)) - end - end. - -app_dependencies(App) -> - case application:get_key(App, applications) of - undefined -> []; - {ok, Lst} -> Lst - end. - -start_applications(Apps) -> - manage_applications(fun lists:foldl/3, - fun application:start/1, - fun application:stop/1, - already_started, - cannot_start_application, - Apps). - -stop_applications(Apps) -> - manage_applications(fun lists:foldr/3, - fun application:stop/1, - fun application:start/1, - not_started, - cannot_stop_application, - 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 - 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) - end. - unfold(Fun, Init) -> unfold(Fun, [], Init). diff --git a/src/rabbit_networking.erl b/src/rabbit_networking.erl index f0c75d23f4..4562608a45 100644 --- a/src/rabbit_networking.erl +++ b/src/rabbit_networking.erl @@ -147,7 +147,7 @@ start() -> ok. ensure_ssl() -> - ok = rabbit_misc:start_applications([crypto, public_key, ssl]), + ok = app_utils:start_applications([crypto, public_key, ssl]), {ok, SslOptsConfig} = application:get_env(rabbit, ssl_options), % unknown_ca errors are silently ignored prior to R14B unless we |
