summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTony Garnock-Jones <tonyg@lshift.net>2009-12-14 18:31:30 +0000
committerTony Garnock-Jones <tonyg@lshift.net>2009-12-14 18:31:30 +0000
commit9b9bc357ab121d268e06ca317537091fe230de79 (patch)
treebf361091c2ea91d3b7d68cced692fbf34dfcaa65
parent3bddf43fcd9f52e5f0d7d66f2a39d458bd739de7 (diff)
downloadrabbitmq-server-9b9bc357ab121d268e06ca317537091fe230de79.tar.gz
Enforce acyclicity; check presence and export of steps.
-rw-r--r--src/rabbit_plugin_activator.erl40
1 files changed, 36 insertions, 4 deletions
diff --git a/src/rabbit_plugin_activator.erl b/src/rabbit_plugin_activator.erl
index 6f6dd2ed..8bf16bec 100644
--- a/src/rabbit_plugin_activator.erl
+++ b/src/rabbit_plugin_activator.erl
@@ -163,12 +163,12 @@ boot_steps(AllApps) ->
sort_boot_steps(UnsortedSteps).
sort_boot_steps(UnsortedSteps) ->
- G = digraph:new(),
+ G = digraph:new([acyclic]),
[digraph:add_vertex(G, ModFunSpec, Step) || Step = {ModFunSpec, _Attrs} <- UnsortedSteps],
lists:foreach(fun ({ModFunSpec, Attributes}) ->
- [digraph:add_edge(G, ModFunSpec, PostModFunSpec)
+ [add_boot_step_dep(G, ModFunSpec, PostModFunSpec)
|| {post, PostModFunSpec} <- Attributes],
- [digraph:add_edge(G, PreModFunSpec, ModFunSpec)
+ [add_boot_step_dep(G, PreModFunSpec, ModFunSpec)
|| {pre, PreModFunSpec} <- Attributes]
end, UnsortedSteps),
SortedStepsRev = [begin
@@ -177,7 +177,39 @@ sort_boot_steps(UnsortedSteps) ->
end || ModFunSpec <- digraph_utils:topsort(G)],
SortedSteps = lists:reverse(SortedStepsRev),
digraph:delete(G),
- SortedSteps.
+ check_boot_steps(SortedSteps).
+
+add_boot_step_dep(G, RunsSecond, RunsFirst) ->
+ case digraph:add_edge(G, RunsSecond, RunsFirst) of
+ {error, Reason} ->
+ error("Could not add boot step dependency of ~s on ~s:~n~s",
+ [format_modfunspec(RunsSecond), format_modfunspec(RunsFirst),
+ case Reason of
+ {bad_vertex, V} ->
+ io_lib:format("Boot step not registered: ~s~n",
+ [format_modfunspec(V)]);
+ {bad_edge, [First | Rest]} ->
+ [io_lib:format("Cyclic dependency: ~s", [format_modfunspec(First)]),
+ [io_lib:format(" depends on ~s", [format_modfunspec(Next)])
+ || Next <- Rest],
+ io_lib:format(" depends on ~s~n", [format_modfunspec(First)])]
+ end]);
+ _ ->
+ ok
+ end.
+
+check_boot_steps(SortedSteps) ->
+ case [ModFunSpec || {ModFunSpec = {Module, {Fun, Arity}}, _} <- SortedSteps,
+ not erlang:function_exported(Module, Fun, Arity)] of
+ [] ->
+ SortedSteps;
+ MissingFunctions ->
+ error("Boot steps not exported:~s~n",
+ [[[" ", format_modfunspec(MFS)] || MFS <- MissingFunctions]])
+ end.
+
+format_modfunspec({Module, {Fun, Arity}}) ->
+ lists:flatten(io_lib:format("~w:~w/~b", [Module, Fun, Arity])).
assert_dir(Dir) ->
case filelib:is_dir(Dir) of