summaryrefslogtreecommitdiff
path: root/src/rabbit.erl
diff options
context:
space:
mode:
authorMatthew Sackman <matthew@rabbitmq.com>2011-08-08 17:15:52 +0100
committerMatthew Sackman <matthew@rabbitmq.com>2011-08-08 17:15:52 +0100
commit14191a156a4be97d87dae99bae3b88d196d9f4e0 (patch)
tree20d3c0f73515e2c7aa3028eba46517068876d467 /src/rabbit.erl
parentbffc69e2d6adeddf85bbb8e9e161539a73f9ac1d (diff)
parent79107abf5327f561ad20f294ac80857a2758e596 (diff)
downloadrabbitmq-server-git-14191a156a4be97d87dae99bae3b88d196d9f4e0.tar.gz
Merging v2_5 branch to default
Diffstat (limited to 'src/rabbit.erl')
-rw-r--r--src/rabbit.erl285
1 files changed, 172 insertions, 113 deletions
diff --git a/src/rabbit.erl b/src/rabbit.erl
index 8866a1b738..e067607da6 100644
--- a/src/rabbit.erl
+++ b/src/rabbit.erl
@@ -23,7 +23,7 @@
-export([start/2, stop/1]).
--export([log_location/1]).
+-export([log_location/1]). %% for testing
%%---------------------------------------------------------------------------
%% Boot steps.
@@ -134,6 +134,18 @@
{requires, empty_db_check},
{enables, routing_ready}]}).
+-rabbit_boot_step({mirror_queue_slave_sup,
+ [{description, "mirror queue slave sup"},
+ {mfa, {rabbit_mirror_queue_slave_sup, start, []}},
+ {requires, recovery},
+ {enables, routing_ready}]}).
+
+-rabbit_boot_step({mirrored_queues,
+ [{description, "adding mirrors to queues"},
+ {mfa, {rabbit_mirror_queue_misc, on_node_up, []}},
+ {requires, mirror_queue_slave_sup},
+ {enables, routing_ready}]}).
+
-rabbit_boot_step({routing_ready,
[{description, "message delivery logic ready"},
{requires, core_initialized}]}).
@@ -201,14 +213,14 @@ prepare() ->
start() ->
try
ok = prepare(),
- ok = rabbit_misc:start_applications(?APPS)
+ ok = rabbit_misc:start_applications(application_load_order())
after
%%give the error loggers some time to catch up
timer:sleep(100)
end.
stop() ->
- ok = rabbit_misc:stop_applications(?APPS).
+ ok = rabbit_misc:stop_applications(application_load_order()).
stop_and_halt() ->
try
@@ -267,20 +279,51 @@ stop(_State) ->
ok.
%%---------------------------------------------------------------------------
+%% application life cycle
+
+application_load_order() ->
+ ok = load_applications(),
+ {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()]),
+ true = digraph:del_vertices(
+ G, digraph:vertices(G) -- digraph_utils:reachable(?APPS, G)),
+ Result = digraph_utils:topsort(G),
+ true = digraph:delete(G),
+ Result.
+
+load_applications() ->
+ load_applications(queue:from_list(?APPS), sets:new()).
+
+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.
-erts_version_check() ->
- FoundVer = erlang:system_info(version),
- case rabbit_misc:version_compare(?ERTS_MINIMUM, FoundVer, lte) of
- true -> ok;
- false -> {error, {erlang_version_too_old,
- {found, FoundVer}, {required, ?ERTS_MINIMUM}}}
+app_dependencies(App) ->
+ case application:get_key(App, applications) of
+ undefined -> [];
+ {ok, Lst} -> Lst
end.
-boot_error(Format, Args) ->
- io:format("BOOT ERROR: " ++ Format, Args),
- error_logger:error_msg(Format, Args),
- timer:sleep(1000),
- exit({?MODULE, failure_during_boot}).
+%%---------------------------------------------------------------------------
+%% boot step logic
run_boot_step({StepName, Attributes}) ->
Description = case lists:keysearch(description, 1, Attributes) of
@@ -355,83 +398,46 @@ sort_boot_steps(UnsortedSteps) ->
end])
end.
+boot_error(Format, Args) ->
+ io:format("BOOT ERROR: " ++ Format, Args),
+ error_logger:error_msg(Format, Args),
+ timer:sleep(1000),
+ exit({?MODULE, failure_during_boot}).
+
%%---------------------------------------------------------------------------
+%% boot step functions
-log_location(Type) ->
- case application:get_env(Type, case Type of
- kernel -> error_logger;
- sasl -> sasl_error_logger
- end) of
- {ok, {file, File}} -> File;
- {ok, false} -> undefined;
- {ok, tty} -> tty;
- {ok, silent} -> undefined;
- {ok, Bad} -> throw({error, {cannot_log_to_file, Bad}});
- _ -> undefined
- end.
+boot_delegate() ->
+ {ok, Count} = application:get_env(rabbit, delegate_count),
+ rabbit_sup:start_child(delegate_sup, [Count]).
-app_location() ->
- {ok, Application} = application:get_application(),
- filename:absname(code:where_is_file(atom_to_list(Application) ++ ".app")).
+recover() ->
+ rabbit_binding:recover(rabbit_exchange:recover(), rabbit_amqqueue:start()).
-home_dir() ->
- case init:get_argument(home) of
- {ok, [[Home]]} -> Home;
- Other -> Other
+maybe_insert_default_data() ->
+ case rabbit_mnesia:is_db_empty() of
+ true -> insert_default_data();
+ false -> ok
end.
-config_files() ->
- case init:get_argument(config) of
- {ok, Files} -> [filename:absname(
- filename:rootname(File, ".config") ++ ".config") ||
- File <- Files];
- error -> []
- end.
+insert_default_data() ->
+ {ok, DefaultUser} = application:get_env(default_user),
+ {ok, DefaultPass} = application:get_env(default_pass),
+ {ok, DefaultTags} = application:get_env(default_user_tags),
+ {ok, DefaultVHost} = application:get_env(default_vhost),
+ {ok, [DefaultConfigurePerm, DefaultWritePerm, DefaultReadPerm]} =
+ application:get_env(default_permissions),
+ ok = rabbit_vhost:add(DefaultVHost),
+ ok = rabbit_auth_backend_internal:add_user(DefaultUser, DefaultPass),
+ ok = rabbit_auth_backend_internal:set_tags(DefaultUser, DefaultTags),
+ ok = rabbit_auth_backend_internal:set_permissions(DefaultUser, DefaultVHost,
+ DefaultConfigurePerm,
+ DefaultWritePerm,
+ DefaultReadPerm),
+ ok.
%%---------------------------------------------------------------------------
-
-print_banner() ->
- {ok, Product} = application:get_key(id),
- {ok, Version} = application:get_key(vsn),
- ProductLen = string:len(Product),
- io:format("~n"
- "+---+ +---+~n"
- "| | | |~n"
- "| | | |~n"
- "| | | |~n"
- "| +---+ +-------+~n"
- "| |~n"
- "| ~s +---+ |~n"
- "| | | |~n"
- "| ~s +---+ |~n"
- "| |~n"
- "+-------------------+~n"
- "~s~n~s~n~s~n~n",
- [Product, string:right([$v|Version], ProductLen),
- ?PROTOCOL_VERSION,
- ?COPYRIGHT_MESSAGE, ?INFORMATION_MESSAGE]),
- Settings = [{"node", node()},
- {"app descriptor", app_location()},
- {"home dir", home_dir()},
- {"config file(s)", config_files()},
- {"cookie hash", rabbit_misc:cookie_hash()},
- {"log", log_location(kernel)},
- {"sasl log", log_location(sasl)},
- {"database dir", rabbit_mnesia:dir()},
- {"erlang version", erlang:system_info(version)}],
- DescrLen = 1 + lists:max([length(K) || {K, _V} <- Settings]),
- Format = fun (K, V) ->
- io:format("~-" ++ integer_to_list(DescrLen) ++ "s: ~s~n",
- [K, V])
- end,
- lists:foreach(fun ({"config file(s)" = K, []}) ->
- Format(K, "(none)");
- ({"config file(s)" = K, [V0 | Vs]}) ->
- Format(K, V0), [Format("", V) || V <- Vs];
- ({K, V}) ->
- Format(K, V)
- end, Settings),
- io:nl().
+%% logging
ensure_working_log_handlers() ->
Handlers = gen_event:which_handlers(error_logger),
@@ -470,38 +476,19 @@ ensure_working_log_handler(OldFHandler, NewFHandler, TTYHandler,
end
end.
-boot_delegate() ->
- {ok, Count} = application:get_env(rabbit, delegate_count),
- rabbit_sup:start_child(delegate_sup, [Count]).
-
-recover() ->
- rabbit_binding:recover(rabbit_exchange:recover(), rabbit_amqqueue:start()).
-
-maybe_insert_default_data() ->
- case rabbit_mnesia:is_db_empty() of
- true -> insert_default_data();
- false -> ok
+log_location(Type) ->
+ case application:get_env(Type, case Type of
+ kernel -> error_logger;
+ sasl -> sasl_error_logger
+ end) of
+ {ok, {file, File}} -> File;
+ {ok, false} -> undefined;
+ {ok, tty} -> tty;
+ {ok, silent} -> undefined;
+ {ok, Bad} -> throw({error, {cannot_log_to_file, Bad}});
+ _ -> undefined
end.
-insert_default_data() ->
- {ok, DefaultUser} = application:get_env(default_user),
- {ok, DefaultPass} = application:get_env(default_pass),
- {ok, DefaultAdmin} = application:get_env(default_user_is_admin),
- {ok, DefaultVHost} = application:get_env(default_vhost),
- {ok, [DefaultConfigurePerm, DefaultWritePerm, DefaultReadPerm]} =
- application:get_env(default_permissions),
- ok = rabbit_vhost:add(DefaultVHost),
- ok = rabbit_auth_backend_internal:add_user(DefaultUser, DefaultPass),
- case DefaultAdmin of
- true -> rabbit_auth_backend_internal:set_admin(DefaultUser);
- _ -> ok
- end,
- ok = rabbit_auth_backend_internal:set_permissions(DefaultUser, DefaultVHost,
- DefaultConfigurePerm,
- DefaultWritePerm,
- DefaultReadPerm),
- ok.
-
rotate_logs(File, Suffix, Handler) ->
rotate_logs(File, Suffix, Handler, Handler).
@@ -524,3 +511,75 @@ log_rotation_result(ok, {error, SaslLogError}) ->
{error, {cannot_rotate_sasl_logs, SaslLogError}};
log_rotation_result(ok, ok) ->
ok.
+
+%%---------------------------------------------------------------------------
+%% misc
+
+erts_version_check() ->
+ FoundVer = erlang:system_info(version),
+ case rabbit_misc:version_compare(?ERTS_MINIMUM, FoundVer, lte) of
+ true -> ok;
+ false -> {error, {erlang_version_too_old,
+ {found, FoundVer}, {required, ?ERTS_MINIMUM}}}
+ end.
+
+print_banner() ->
+ {ok, Product} = application:get_key(id),
+ {ok, Version} = application:get_key(vsn),
+ ProductLen = string:len(Product),
+ io:format("~n"
+ "+---+ +---+~n"
+ "| | | |~n"
+ "| | | |~n"
+ "| | | |~n"
+ "| +---+ +-------+~n"
+ "| |~n"
+ "| ~s +---+ |~n"
+ "| | | |~n"
+ "| ~s +---+ |~n"
+ "| |~n"
+ "+-------------------+~n"
+ "~s~n~s~n~s~n~n",
+ [Product, string:right([$v|Version], ProductLen),
+ ?PROTOCOL_VERSION,
+ ?COPYRIGHT_MESSAGE, ?INFORMATION_MESSAGE]),
+ Settings = [{"node", node()},
+ {"app descriptor", app_location()},
+ {"home dir", home_dir()},
+ {"config file(s)", config_files()},
+ {"cookie hash", rabbit_misc:cookie_hash()},
+ {"log", log_location(kernel)},
+ {"sasl log", log_location(sasl)},
+ {"database dir", rabbit_mnesia:dir()},
+ {"erlang version", erlang:system_info(version)}],
+ DescrLen = 1 + lists:max([length(K) || {K, _V} <- Settings]),
+ Format = fun (K, V) ->
+ io:format("~-" ++ integer_to_list(DescrLen) ++ "s: ~s~n",
+ [K, V])
+ end,
+ lists:foreach(fun ({"config file(s)" = K, []}) ->
+ Format(K, "(none)");
+ ({"config file(s)" = K, [V0 | Vs]}) ->
+ Format(K, V0), [Format("", V) || V <- Vs];
+ ({K, V}) ->
+ Format(K, V)
+ end, Settings),
+ io:nl().
+
+app_location() ->
+ {ok, Application} = application:get_application(),
+ filename:absname(code:where_is_file(atom_to_list(Application) ++ ".app")).
+
+home_dir() ->
+ case init:get_argument(home) of
+ {ok, [[Home]]} -> Home;
+ Other -> Other
+ end.
+
+config_files() ->
+ case init:get_argument(config) of
+ {ok, Files} -> [filename:absname(
+ filename:rootname(File, ".config") ++ ".config") ||
+ File <- Files];
+ error -> []
+ end.