diff options
author | Tony Garnock-Jones <tonyg@lshift.net> | 2009-12-14 18:31:30 +0000 |
---|---|---|
committer | Tony Garnock-Jones <tonyg@lshift.net> | 2009-12-14 18:31:30 +0000 |
commit | 9b9bc357ab121d268e06ca317537091fe230de79 (patch) | |
tree | bf361091c2ea91d3b7d68cced692fbf34dfcaa65 | |
parent | 3bddf43fcd9f52e5f0d7d66f2a39d458bd739de7 (diff) | |
download | rabbitmq-server-9b9bc357ab121d268e06ca317537091fe230de79.tar.gz |
Enforce acyclicity; check presence and export of steps.
-rw-r--r-- | src/rabbit_plugin_activator.erl | 40 |
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 |