diff options
author | Simon MacMullen <simon@rabbitmq.com> | 2011-12-01 18:11:17 +0000 |
---|---|---|
committer | Simon MacMullen <simon@rabbitmq.com> | 2011-12-01 18:11:17 +0000 |
commit | caac06859596a032daa8452e37e284a74140c1ed (patch) | |
tree | d30c0569c9ae95e76799ff6523bfa225dd6670c3 | |
parent | bf479646c91f5dec92d858d02a6b0f97f2cbef17 (diff) | |
download | rabbitmq-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.erl | 33 | ||||
-rw-r--r-- | src/mirrored_supervisor_tests.erl | 4 |
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). %% --------------------------------------------------------------------------- |