summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTony Garnock-Jones <tonyg@lshift.net>2009-12-14 21:45:31 +0000
committerTony Garnock-Jones <tonyg@lshift.net>2009-12-14 21:45:31 +0000
commitfa6b56dbba4f507dc643a6c872731aa2c9dc770b (patch)
tree3b79390a1600a3884b20c4ff3b9e950e0c81037b
parent9b9bc357ab121d268e06ca317537091fe230de79 (diff)
downloadrabbitmq-server-fa6b56dbba4f507dc643a6c872731aa2c9dc770b.tar.gz
Move planning code out of activator and into rabbit proper.
-rw-r--r--Makefile1
-rw-r--r--src/rabbit.erl120
-rw-r--r--src/rabbit_plugin_activator.erl77
3 files changed, 95 insertions, 103 deletions
diff --git a/Makefile b/Makefile
index f9af1cbe..1cd48df2 100644
--- a/Makefile
+++ b/Makefile
@@ -57,7 +57,6 @@ ERL_CALL=erl_call -sname $(RABBITMQ_NODENAME) -e
ERL_EBIN=erl -noinput -pa $(EBIN_DIR)
all: $(TARGETS)
- ./scripts/rabbitmq-activate-plugins
$(EBIN_DIR)/rabbit.app: $(EBIN_DIR)/rabbit_app.in $(BEAM_TARGETS) generate_app
escript generate_app $(EBIN_DIR) $@ < $<
diff --git a/src/rabbit.erl b/src/rabbit.erl
index 78bf7e38..dd5f221a 100644
--- a/src/rabbit.erl
+++ b/src/rabbit.erl
@@ -33,7 +33,7 @@
-behaviour(application).
--export([prepare/0, start/0, finish_boot/1, stop/0, stop_and_halt/0, status/0, rotate_logs/1]).
+-export([prepare/0, start/0, stop/0, stop_and_halt/0, status/0, rotate_logs/1]).
-export([start/2, stop/1]).
@@ -80,11 +80,9 @@
-type(log_location() :: 'tty' | 'undefined' | string()).
-type(file_suffix() :: binary()).
--type(boot_step() :: {{atom(), {atom(), 0}}, [{atom(), any()}]}).
-spec(prepare/0 :: () -> 'ok').
-spec(start/0 :: () -> 'ok').
--spec(finish_boot/1 :: ([boot_step()]) -> 'ok').
-spec(stop/0 :: () -> 'ok').
-spec(stop_and_halt/0 :: () -> 'ok').
-spec(rotate_logs/1 :: (file_suffix()) -> 'ok' | {'error', any()}).
@@ -141,24 +139,33 @@ rotate_logs(BinarySuffix) ->
%%--------------------------------------------------------------------
start(normal, []) ->
- {ok, _SupPid} = rabbit_sup:start_link().
-
-finish_boot(BootSteps) ->
- %% We set our group_leader so we appear to OTP to be part of the
- %% rabbit application.
- case application_controller:get_master(rabbit) of
- undefined ->
- exit({?MODULE, finish_boot, could_not_find_rabbit});
- MasterPid when is_pid(MasterPid) ->
- group_leader(MasterPid, self())
- end,
+ {ok, SupPid} = rabbit_sup:start_link(),
print_banner(),
- [ok = run_boot_step(Step) || Step <- BootSteps],
+ [ok = run_boot_step(Step) || Step <- boot_steps()],
io:format("~nbroker running~n"),
+
+ {ok, SupPid}.
+
+
+stop(_State) ->
+ terminated_ok = error_logger:delete_report_handler(rabbit_error_logger),
+ ok = rabbit_alarm:stop(),
+ ok = case rabbit_mnesia:is_clustered() of
+ true -> rabbit_amqqueue:on_node_down(node());
+ false -> rabbit_mnesia:empty_ram_only_tables()
+ end,
ok.
-run_boot_step({ModFunSpec = {Module, {Fun, 0}}, Attributes}) ->
+%%---------------------------------------------------------------------------
+
+boot_error(Format, Args) ->
+ io:format(Format, Args),
+ error_logger:error_msg(Format, Args),
+ timer:sleep(1000),
+ exit({?MODULE, failure_during_boot}).
+
+run_boot_step({{Module, {Fun, 0}}, Attributes}) ->
Description = case lists:keysearch(description, 1, Attributes) of
{value, {_, D}} -> D;
false -> lists:flatten(io_lib:format("~w:~w", [Module, Fun]))
@@ -166,16 +173,78 @@ run_boot_step({ModFunSpec = {Module, {Fun, 0}}, Attributes}) ->
io:format("starting ~-20s ...", [Description]),
case catch Module:Fun() of
{'EXIT', Reason} ->
- io:format("FAILED~nReason: ~p~n", [Reason]),
- ChainedReason = {?MODULE, finish_boot, failed, ModFunSpec, Reason},
- error_logger:error_report(ChainedReason),
- timer:sleep(1000),
- exit(ChainedReason);
+ boot_error("FAILED~nReason: ~p~n", [Reason]);
ok ->
io:format("done~n"),
ok
end.
+boot_steps() ->
+ AllApps = [App || {App, _, _} <- application:loaded_applications()],
+ Modules = lists:usort(
+ lists:append([Modules
+ || {ok, Modules} <- [application:get_key(App, modules)
+ || App <- AllApps]])),
+ UnsortedSteps =
+ lists:flatmap(fun (Module) ->
+ [{{Module, FunSpec}, Attributes}
+ || {rabbit_boot_step, [{FunSpec, Attributes}]}
+ <- Module:module_info(attributes)]
+ end, Modules),
+ sort_boot_steps(UnsortedSteps).
+
+sort_boot_steps(UnsortedSteps) ->
+ G = digraph:new([acyclic]),
+ [digraph:add_vertex(G, ModFunSpec, Step) || Step = {ModFunSpec, _Attrs} <- UnsortedSteps],
+ lists:foreach(fun ({ModFunSpec, Attributes}) ->
+ [add_boot_step_dep(G, ModFunSpec, PostModFunSpec)
+ || {post, PostModFunSpec} <- Attributes],
+ [add_boot_step_dep(G, PreModFunSpec, ModFunSpec)
+ || {pre, PreModFunSpec} <- Attributes]
+ end, UnsortedSteps),
+ SortedStepsRev = [begin
+ {ModFunSpec, Step} = digraph:vertex(G, ModFunSpec),
+ Step
+ end || ModFunSpec <- digraph_utils:topsort(G)],
+ SortedSteps = lists:reverse(SortedStepsRev),
+ digraph:delete(G),
+ check_boot_steps(SortedSteps).
+
+add_boot_step_dep(G, RunsSecond, RunsFirst) ->
+ case digraph:add_edge(G, RunsSecond, RunsFirst) of
+ {error, Reason} ->
+ boot_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 ->
+ boot_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])).
+
+%%---------------------------------------------------------------------------
+
boot_database() ->
ok = rabbit_mnesia:init().
@@ -235,15 +304,6 @@ boot_ssl_listeners() ->
ok
end.
-stop(_State) ->
- terminated_ok = error_logger:delete_report_handler(rabbit_error_logger),
- ok = rabbit_alarm:stop(),
- ok = case rabbit_mnesia:is_clustered() of
- true -> rabbit_amqqueue:on_node_down(node());
- false -> rabbit_mnesia:empty_ram_only_tables()
- end,
- ok.
-
%---------------------------------------------------------------------------
log_location(Type) ->
diff --git a/src/rabbit_plugin_activator.erl b/src/rabbit_plugin_activator.erl
index 8bf16bec..4fcfab78 100644
--- a/src/rabbit_plugin_activator.erl
+++ b/src/rabbit_plugin_activator.erl
@@ -121,7 +121,7 @@ start() ->
[ScriptFile, Module:format_error(Error)])
end,
- case post_process_script(ScriptFile, boot_steps(AllApps)) of
+ case post_process_script(ScriptFile) of
ok -> ok;
{error, Reason} ->
error("post processing of boot script file ~s failed:~n~w",
@@ -148,69 +148,6 @@ determine_version(App) ->
{ok, Vsn} = application:get_key(App, vsn),
{App, Vsn}.
-boot_steps(AllApps) ->
- [application:load(App) || App <- AllApps],
- Modules = lists:usort(
- lists:append([Modules
- || {ok, Modules} <- [application:get_key(App, modules)
- || App <- AllApps]])),
- UnsortedSteps =
- lists:flatmap(fun (Module) ->
- [{{Module, FunSpec}, Attributes}
- || {rabbit_boot_step, [{FunSpec, Attributes}]}
- <- Module:module_info(attributes)]
- end, Modules),
- sort_boot_steps(UnsortedSteps).
-
-sort_boot_steps(UnsortedSteps) ->
- G = digraph:new([acyclic]),
- [digraph:add_vertex(G, ModFunSpec, Step) || Step = {ModFunSpec, _Attrs} <- UnsortedSteps],
- lists:foreach(fun ({ModFunSpec, Attributes}) ->
- [add_boot_step_dep(G, ModFunSpec, PostModFunSpec)
- || {post, PostModFunSpec} <- Attributes],
- [add_boot_step_dep(G, PreModFunSpec, ModFunSpec)
- || {pre, PreModFunSpec} <- Attributes]
- end, UnsortedSteps),
- SortedStepsRev = [begin
- {ModFunSpec, Step} = digraph:vertex(G, ModFunSpec),
- Step
- end || ModFunSpec <- digraph_utils:topsort(G)],
- SortedSteps = lists:reverse(SortedStepsRev),
- digraph:delete(G),
- 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
true -> ok;
@@ -290,12 +227,10 @@ expand_dependencies(Current, [Next|Rest]) ->
expand_dependencies(sets:add_element(Next, Current), Rest ++ Unique)
end.
-post_process_script(ScriptFile, BootSteps) ->
+post_process_script(ScriptFile) ->
case file:consult(ScriptFile) of
{ok, [{script, Name, Entries}]} ->
- NewEntries = lists:flatmap(fun (Entry) ->
- process_entry(Entry, BootSteps)
- end, Entries),
+ NewEntries = lists:flatmap(fun process_entry/1, Entries),
case file:open(ScriptFile, [write]) of
{ok, Fd} ->
io:format(Fd, "%% script generated at ~w ~w~n~p.~n",
@@ -309,11 +244,9 @@ post_process_script(ScriptFile, BootSteps) ->
{error, {failed_to_load_script, Reason}}
end.
-process_entry(Entry = {apply,{application,start_boot,[stdlib,permanent]}}, _BootSteps) ->
+process_entry(Entry = {apply,{application,start_boot,[stdlib,permanent]}}) ->
[Entry, {apply,{rabbit,prepare,[]}}];
-process_entry(Entry = {progress, started}, BootSteps) ->
- [{apply,{rabbit,finish_boot,[BootSteps]}}, Entry];
-process_entry(Entry, _BootSteps) ->
+process_entry(Entry) ->
[Entry].
error(Fmt, Args) ->