summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon MacMullen <simon@rabbitmq.com>2011-12-01 18:11:17 +0000
committerSimon MacMullen <simon@rabbitmq.com>2011-12-01 18:11:17 +0000
commitcaac06859596a032daa8452e37e284a74140c1ed (patch)
treed30c0569c9ae95e76799ff6523bfa225dd6670c3
parentbf479646c91f5dec92d858d02a6b0f97f2cbef17 (diff)
downloadrabbitmq-server-caac06859596a032daa8452e37e284a74140c1ed.tar.gz
Handle children that fail to start at init properly, by shutting down.
Maybe we should log something though.
-rw-r--r--src/mirrored_supervisor.erl33
-rw-r--r--src/mirrored_supervisor_tests.erl4
2 files changed, 24 insertions, 13 deletions
diff --git a/src/mirrored_supervisor.erl b/src/mirrored_supervisor.erl
index 8dfe39f8..45be277e 100644
--- a/src/mirrored_supervisor.erl
+++ b/src/mirrored_supervisor.erl
@@ -242,8 +242,10 @@ start_link({global, _SupName}, _Group, _Mod, _Args) ->
start_link0(Prefix, Group, Init) ->
case apply(?SUPERVISOR, start_link,
Prefix ++ [?MODULE, {overall, Group, Init}]) of
- {ok, Pid} -> call(Pid, {init, Pid}),
- {ok, Pid};
+ {ok, Pid} -> case catch call(Pid, {init, Pid}) of
+ ok -> {ok, Pid};
+ E -> E
+ end;
Other -> Other
end.
@@ -346,8 +348,11 @@ handle_call({init, Overall}, _From,
end || Pid <- Rest],
Delegate = child(Overall, delegate),
erlang:monitor(process, Delegate),
- [maybe_start(Group, Delegate, S) || S <- ChildSpecs],
- {reply, ok, State#state{overall = Overall, delegate = Delegate}};
+ State1 = State#state{overall = Overall, delegate = Delegate},
+ case all_started([maybe_start(Group, Delegate, S) || S <- ChildSpecs]) of
+ true -> {reply, ok, State1};
+ false -> {stop, shutdown, State1}
+ end;
handle_call({start_child, ChildSpec}, _From,
State = #state{delegate = Delegate,
@@ -400,13 +405,16 @@ handle_info({'DOWN', _Ref, process, Pid, _Reason},
%% TODO load balance this
%% No guarantee pg2 will have received the DOWN before us.
Self = self(),
- case lists:sort(?PG2:get_members(Group)) -- [Pid] of
- [Self | _] -> {atomic, ChildSpecs} =
- mnesia:transaction(fun() -> update_all(Pid) end),
- [start(Delegate, ChildSpec) || ChildSpec <- ChildSpecs];
- _ -> ok
- end,
- {noreply, State};
+ R = case lists:sort(?PG2:get_members(Group)) -- [Pid] of
+ [Self | _] -> {atomic, ChildSpecs} =
+ mnesia:transaction(fun() -> update_all(Pid) end),
+ [start(Delegate, ChildSpec) || ChildSpec <- ChildSpecs];
+ _ -> ok
+ end,
+ case all_started(R) of
+ true -> {noreply, State};
+ false -> {stop, shutdown, State}
+ end;
handle_info(Info, State) ->
{stop, {unexpected_info, Info}, State}.
@@ -499,6 +507,9 @@ delete_all(Group) ->
[delete(Group, id(C)) ||
C <- mnesia:select(?TABLE, [{MatchHead, [], ['$1']}])].
+all_started(Results) ->
+ [] =:= [R || R = {error, _} <- Results].
+
%%----------------------------------------------------------------------------
create_tables() ->
diff --git a/src/mirrored_supervisor_tests.erl b/src/mirrored_supervisor_tests.erl
index f2ae7e4e..d87fddd1 100644
--- a/src/mirrored_supervisor_tests.erl
+++ b/src/mirrored_supervisor_tests.erl
@@ -206,13 +206,13 @@ test_startup_failure(Fail) ->
process_flag(trap_exit, true),
?MS:start_link(get_group(group), ?MODULE,
{sup, one_for_one, [childspec(Fail)]}),
- process_flag(trap_exit, false),
receive
{'EXIT', _, shutdown} ->
ok
after 1000 ->
exit({did_not_exit, Fail})
- end.
+ end,
+ process_flag(trap_exit, false).
%% ---------------------------------------------------------------------------