Skip to content

Commit e724430

Browse files
author
Emile Joubert
committed
Merged bug24612 into default
2 parents 1aac220 + 3dfc9e0 commit e724430

File tree

2 files changed

+51
-14
lines changed

2 files changed

+51
-14
lines changed

src/mirrored_supervisor.erl

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -242,8 +242,10 @@ start_link({global, _SupName}, _Group, _Mod, _Args) ->
242242
start_link0(Prefix, Group, Init) ->
243243
case apply(?SUPERVISOR, start_link,
244244
Prefix ++ [?MODULE, {overall, Group, Init}]) of
245-
{ok, Pid} -> call(Pid, {init, Pid}),
246-
{ok, Pid};
245+
{ok, Pid} -> case catch call(Pid, {init, Pid}) of
246+
ok -> {ok, Pid};
247+
E -> E
248+
end;
247249
Other -> Other
248250
end.
249251

@@ -346,13 +348,20 @@ handle_call({init, Overall}, _From,
346348
end || Pid <- Rest],
347349
Delegate = child(Overall, delegate),
348350
erlang:monitor(process, Delegate),
349-
[maybe_start(Group, Delegate, S) || S <- ChildSpecs],
350-
{reply, ok, State#state{overall = Overall, delegate = Delegate}};
351+
State1 = State#state{overall = Overall, delegate = Delegate},
352+
case all_started([maybe_start(Group, Delegate, S) || S <- ChildSpecs]) of
353+
true -> {reply, ok, State1};
354+
false -> {stop, shutdown, State1}
355+
end;
351356

352357
handle_call({start_child, ChildSpec}, _From,
353358
State = #state{delegate = Delegate,
354359
group = Group}) ->
355-
{reply, maybe_start(Group, Delegate, ChildSpec), State};
360+
{reply, case maybe_start(Group, Delegate, ChildSpec) of
361+
already_in_mnesia -> {error, already_present};
362+
{already_in_mnesia, Pid} -> {error, {already_started, Pid}};
363+
Else -> Else
364+
end, State};
356365

357366
handle_call({delete_child, Id}, _From, State = #state{delegate = Delegate,
358367
group = Group}) ->
@@ -400,13 +409,16 @@ handle_info({'DOWN', _Ref, process, Pid, _Reason},
400409
%% TODO load balance this
401410
%% No guarantee pg2 will have received the DOWN before us.
402411
Self = self(),
403-
case lists:sort(?PG2:get_members(Group)) -- [Pid] of
404-
[Self | _] -> {atomic, ChildSpecs} =
405-
mnesia:transaction(fun() -> update_all(Pid) end),
406-
[start(Delegate, ChildSpec) || ChildSpec <- ChildSpecs];
407-
_ -> ok
408-
end,
409-
{noreply, State};
412+
R = case lists:sort(?PG2:get_members(Group)) -- [Pid] of
413+
[Self | _] -> {atomic, ChildSpecs} =
414+
mnesia:transaction(fun() -> update_all(Pid) end),
415+
[start(Delegate, ChildSpec) || ChildSpec <- ChildSpecs];
416+
_ -> []
417+
end,
418+
case all_started(R) of
419+
true -> {noreply, State};
420+
false -> {stop, shutdown, State}
421+
end;
410422

411423
handle_info(Info, State) ->
412424
{stop, {unexpected_info, Info}, State}.
@@ -428,8 +440,8 @@ maybe_start(Group, Delegate, ChildSpec) ->
428440
check_start(Group, Delegate, ChildSpec)
429441
end) of
430442
{atomic, start} -> start(Delegate, ChildSpec);
431-
{atomic, undefined} -> {error, already_present};
432-
{atomic, Pid} -> {error, {already_started, Pid}};
443+
{atomic, undefined} -> already_in_mnesia;
444+
{atomic, Pid} -> {already_in_mnesia, Pid};
433445
%% If we are torn down while in the transaction...
434446
{aborted, E} -> {error, E}
435447
end.
@@ -499,6 +511,8 @@ delete_all(Group) ->
499511
[delete(Group, id(C)) ||
500512
C <- mnesia:select(?TABLE, [{MatchHead, [], ['$1']}])].
501513

514+
all_started(Results) -> [] =:= [R || R = {error, _} <- Results].
515+
502516
%%----------------------------------------------------------------------------
503517

504518
create_tables() ->

src/mirrored_supervisor_tests.erl

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ all_tests() ->
4545
passed = test_start_idempotence(),
4646
passed = test_unsupported(),
4747
passed = test_ignore(),
48+
passed = test_startup_failure(),
4849
passed.
4950

5051
%% Simplest test
@@ -197,6 +198,22 @@ test_ignore() ->
197198
{sup, fake_strategy_for_ignore, []}),
198199
passed.
199200

201+
test_startup_failure() ->
202+
[test_startup_failure(F) || F <- [want_error, want_exit]],
203+
passed.
204+
205+
test_startup_failure(Fail) ->
206+
process_flag(trap_exit, true),
207+
?MS:start_link(get_group(group), ?MODULE,
208+
{sup, one_for_one, [childspec(Fail)]}),
209+
receive
210+
{'EXIT', _, shutdown} ->
211+
ok
212+
after 1000 ->
213+
exit({did_not_exit, Fail})
214+
end,
215+
process_flag(trap_exit, false).
216+
200217
%% ---------------------------------------------------------------------------
201218

202219
with_sups(Fun, Sups) ->
@@ -230,6 +247,12 @@ start_sup0(Name, Group, ChildSpecs) ->
230247
childspec(Id) ->
231248
{Id, {?MODULE, start_gs, [Id]}, transient, 16#ffffffff, worker, [?MODULE]}.
232249

250+
start_gs(want_error) ->
251+
{error, foo};
252+
253+
start_gs(want_exit) ->
254+
exit(foo);
255+
233256
start_gs(Id) ->
234257
gen_server:start_link({local, Id}, ?MODULE, server, []).
235258

0 commit comments

Comments
 (0)