summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Watson <tim@rabbitmq.com>2013-04-19 12:36:55 +0100
committerTim Watson <tim@rabbitmq.com>2013-04-19 12:36:55 +0100
commit6dff79458ef7b54fe9c253414676a44cd323802e (patch)
treec44560cb73547a0298558ee7e43bc06c29523844
parent463fbb4b0c80059d7ad7a5908e06689587f38d50 (diff)
downloadrabbitmq-server-6dff79458ef7b54fe9c253414676a44cd323802e.tar.gz
Refactor restart handling
Avoid logging restart (failures) twice. Do not reset {restarting, Pid} to 'undefined' as this deadlocks the supervisor.
-rw-r--r--src/supervisor2.erl5
-rw-r--r--src/supervisor2_tests.erl58
2 files changed, 60 insertions, 3 deletions
diff --git a/src/supervisor2.erl b/src/supervisor2.erl
index 533ec997..ca219990 100644
--- a/src/supervisor2.erl
+++ b/src/supervisor2.erl
@@ -837,7 +837,7 @@ restart_child(Pid, Reason, State) ->
end.
try_restart(RestartType, Reason, Child, State) ->
- case do_restart(RestartType, Reason, Child, State) of
+ case handle_restart(RestartType, Reason, Child, State) of
{ok, NState} -> {noreply, NState};
{shutdown, State2} -> {stop, shutdown, State2}
end.
@@ -1260,6 +1260,9 @@ state_del_child(Child, State) ->
del_child(Name, [Ch|Chs]) when Ch#child.name =:= Name, Ch#child.restart_type =:= temporary ->
Chs;
+del_child(NameOrPid, [Ch=#child{pid = ?restarting(_)}|_]=Chs)
+ when Ch#child.name =:= NameOrPid ->
+ Chs;
del_child(Name, [Ch|Chs]) when Ch#child.name =:= Name ->
[Ch#child{pid = undefined} | Chs];
del_child(Pid, [Ch|Chs]) when Ch#child.pid =:= Pid, Ch#child.restart_type =:= temporary ->
diff --git a/src/supervisor2_tests.erl b/src/supervisor2_tests.erl
index 518f11b7..c53b613c 100644
--- a/src/supervisor2_tests.erl
+++ b/src/supervisor2_tests.erl
@@ -17,12 +17,22 @@
-module(supervisor2_tests).
-behaviour(supervisor2).
+-include_lib("eunit/include/eunit.hrl").
+
+-define(ASSERT, true).
+-define(EUNIT_NOAUTO, true).
+
-export([test_all/0, start_link/0]).
+-export([start_link_bad/0]).
-export([init/1]).
test_all() ->
- ok = check_shutdown(stop, 200, 200, 2000),
- ok = check_shutdown(ignored, 1, 2, 2000).
+ catch ets:new(?MODULE, [named_table, public]),
+ %% ok = check_shutdown(stop, 200, 200, 2000),
+ %% ok = check_shutdown(ignored, 1, 2, 2000),
+ %% ok = check_logging(transient),
+ ets:delete(?MODULE, bang),
+ ok = check_logging({permanent, 1}).
check_shutdown(SigStop, Iterations, ChildCount, SupTimeout) ->
{ok, Sup} = supervisor2:start_link(?MODULE, [SupTimeout]),
@@ -52,6 +62,20 @@ check_shutdown(SigStop, Iterations, ChildCount, SupTimeout) ->
exit(Sup, shutdown),
Res.
+check_logging(How) ->
+ process_flag(trap_exit, true),
+ {ok, Sup} = supervisor2:start_link(?MODULE, [bang, How]),
+ io:format("super pid = ~p~n", [Sup]),
+ MRef = erlang:monitor(process, Sup),
+ [Pid] = supervisor2:find_child(Sup, test_try_again_sup),
+ io:format("Pid == ~p~nChildren == ~p~n", [Pid, supervisor2:which_children(Sup)]),
+ Pid ! {shutdown, bang},
+ io:format("restart issued - awaiting sup death~n"),
+ receive
+ {'DOWN', MRef, process, Sup, Reason} ->
+ io:format("stopped Sup == ~p~n", [Reason])
+ end.
+
start_link() ->
Pid = spawn_link(fun () ->
process_flag(trap_exit, true),
@@ -59,6 +83,35 @@ start_link() ->
end),
{ok, Pid}.
+start_link_bad() ->
+ Boom = ets:lookup(?MODULE, bang),
+ case Boom of
+ [{bang, true}] -> io:format("BOOM!~n"), exit(bang);
+ _ -> ok
+ end,
+ io:format("no Boom - starting server~n"),
+ Pid = spawn_link(fun () ->
+ process_flag(trap_exit, true),
+ receive
+ {shutdown, Bang} ->
+ ets:insert(?MODULE, [{bang, true}]),
+ io:format("exiting...~n"),
+ exit(Bang);
+ shutdown ->
+ io:format("exiting (shutdown)...~n"),
+ exit(shutdown);
+ Other ->
+ io:format("odd signal: ~p~n", [Other]),
+ exit(Other)
+ end
+ end),
+ {ok, Pid}.
+
+init([bang, How]) ->
+ {ok, {{one_for_one, 3, 10},
+ [{test_try_again_sup, {?MODULE, start_link_bad, []},
+ How, 5000, worker, [?MODULE]}]}};
+
init([Timeout]) ->
{ok, {{one_for_one, 0, 1},
[{test_sup, {supervisor2, start_link,
@@ -68,3 +121,4 @@ init([]) ->
{ok, {{simple_one_for_one, 0, 1},
[{test_worker, {?MODULE, start_link, []},
temporary, 1000, worker, [?MODULE]}]}}.
+