summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Jones <paulj@lshift.net>2009-07-23 09:28:30 +0100
committerPaul Jones <paulj@lshift.net>2009-07-23 09:28:30 +0100
commitd9f176732b734ef1db205a25fa9b5fd65151c749 (patch)
tree91d948cd70792133b007fdc348facad713ead9f3
parent08ba41973dad77dbda82aca7e4f5b959e0223179 (diff)
downloadrabbitmq-server-d9f176732b734ef1db205a25fa9b5fd65151c749.tar.gz
Reworked dependency expansion mechanism to not overexplore known dependencies; eliminated crash-dump when an unknown dependency is encountered
-rw-r--r--src/rabbit_plugin_activator.erl54
1 files changed, 32 insertions, 22 deletions
diff --git a/src/rabbit_plugin_activator.erl b/src/rabbit_plugin_activator.erl
index 4e1c9324..138c3572 100644
--- a/src/rabbit_plugin_activator.erl
+++ b/src/rabbit_plugin_activator.erl
@@ -36,8 +36,9 @@
-define(DefaultPluginDir, "plugins").
-define(DefaultUnpackedPluginDir, "priv/plugins").
-define(DefaultRabbitEBin, "ebin").
--define(BaseApps, [kernel, stdlib, sasl, mnesia, os_mon, rabbit]).
+-define(BaseApps, [rabbit]).
-define(Debug(_F, _V), ok).
+-define(Error(F, V), io:format("ERROR: " ++ F, V)).
%%----------------------------------------------------------------------------
@@ -57,8 +58,13 @@ start() ->
RequiredApps = ?BaseApps ++ find_plugins(PluginDir) ++ find_plugins(UnpackedPluginDir),
% Build the entire set of dependencies - this will load the applications along the way
- AllApps = sets:to_list(fold_dependencies(undefined, RequiredApps)),
-
+ AllApps = case catch sets:to_list(expand_dependencies(RequiredApps)) of
+ {unknown_app, _} ->
+ ?Error("Failed to expand dependencies.~n", []),
+ halt(1);
+ AppList ->
+ AppList
+ end,
AppVersions = [determine_version(App) || App <- AllApps],
{value, {rabbit, RabbitVersion}} = lists:keysearch(rabbit, 1, AppVersions),
@@ -136,22 +142,26 @@ prepare_dir_plugin(PluginAppDescFn) ->
NameTokens = string:tokens(PluginAppDescFn,"/."),
PluginNameString = lists:nth(length(NameTokens) - 1, NameTokens),
list_to_atom(PluginNameString).
-
-fold_dependencies(App, []) ->
- sets:from_list([App]);
-fold_dependencies(App, AppList) ->
- lists:foldl(fun(ChildApp, AccSet) ->
- case application:load(ChildApp) of
- ok -> ok;
- {error, {already_loaded, _}} -> ok;
- X -> io:format("Failed to load ~p: ~p~n", [ChildApp, X])
- end,
- {ok, Required} = application:get_key(ChildApp, applications),
- DepSet = fold_dependencies(ChildApp, Required),
- sets:union(AccSet, DepSet)
- end,
- case App of
- undefined -> sets:new();
- _ -> sets:from_list([App])
- end,
- AppList). \ No newline at end of file
+
+expand_dependencies(Pending) ->
+ expand_dependencies(sets:new(), Pending).
+expand_dependencies(Current, []) ->
+ Current;
+expand_dependencies(Current, [Next|Rest]) ->
+ case sets:is_element(Next, Current) of
+ true ->
+ expand_dependencies(Current, Rest);
+ false ->
+ case application:load(Next) of
+ ok ->
+ ok;
+ {error, {already_loaded, _}} ->
+ ok;
+ X ->
+ ?Error("Failed to load ~s: ~p~n", [Next, X]),
+ throw({unknown_app, Next})
+ end,
+ {ok, Required} = application:get_key(Next, applications),
+ Unique = [A || A <- Required, not(sets:is_element(A, Current))],
+ expand_dependencies(sets:add_element(Next, Current), Rest ++ Unique)
+ end. \ No newline at end of file