diff options
-rw-r--r-- | src/supervisor2.erl | 50 |
1 files changed, 30 insertions, 20 deletions
diff --git a/src/supervisor2.erl b/src/supervisor2.erl index a2f4fae9..774b7007 100644 --- a/src/supervisor2.erl +++ b/src/supervisor2.erl @@ -9,15 +9,15 @@ %% terminated as per the shutdown component of the child_spec. %% %% 3) child specifications can contain, as the restart type, a tuple -%% {permanent, Delay} | {transient, Delay} where Delay >= 0. The -%% delay, in seconds, indicates what should happen if a child, upon -%% being restarted, exceeds the MaxT and MaxR parameters. Thus, if -%% a child exits, it is restarted as normal. If it exits -%% sufficiently quickly and often to exceed the boundaries set by -%% the MaxT and MaxR parameters, and a Delay is specified, then -%% rather than stopping the supervisor, the supervisor instead -%% continues and tries to start up the child again, Delay seconds -%% later. +%% {permanent, Delay} | {transient, Delay} | {intrinsic, Delay} +%% where Delay >= 0 (see point (4) below for intrinsic). The delay, +%% in seconds, indicates what should happen if a child, upon being +%% restarted, exceeds the MaxT and MaxR parameters. Thus, if a +%% child exits, it is restarted as normal. If it exits sufficiently +%% quickly and often to exceed the boundaries set by the MaxT and +%% MaxR parameters, and a Delay is specified, then rather than +%% stopping the supervisor, the supervisor instead continues and +%% tries to start up the child again, Delay seconds later. %% %% Note that you can never restart more frequently than the MaxT %% and MaxR parameters allow: i.e. you must wait until *both* the @@ -529,16 +529,8 @@ restart_child(Pid, Reason, State) -> {ok, State} end. -do_restart({RestartType, Delay}, Reason, Child, State) -> - case restart1(Child, State) of - {ok, NState} -> - {ok, NState}; - {terminate, NState} -> - _TRef = erlang:send_after(trunc(Delay*1000), self(), - {delayed_restart, - {{RestartType, Delay}, Reason, Child}}), - {ok, state_del_child(Child, NState)} - end; +do_restart({permanent = RestartType, Delay}, Reason, Child, State) -> + do_restart_delay({RestartType, Delay}, Reason, Child, State); do_restart(permanent, Reason, Child, State) -> report_error(child_terminated, Reason, Child, State#state.name), restart(Child, State); @@ -548,6 +540,9 @@ do_restart(Type, {shutdown, _}, Child, State) -> del_child_and_maybe_shutdown(Type, Child, State); do_restart(Type, shutdown, Child = #child{child_type = supervisor}, State) -> del_child_and_maybe_shutdown(Type, Child, State); +do_restart({RestartType, Delay}, Reason, Child, State) + when RestartType =:= transient orelse RestartType =:= intrinsic -> + do_restart_delay({RestartType, Delay}, Reason, Child, State); do_restart(Type, Reason, Child, State) when Type =:= transient orelse Type =:= intrinsic -> report_error(child_terminated, Reason, Child, State#state.name), @@ -557,8 +552,21 @@ do_restart(temporary, Reason, Child, State) -> NState = state_del_child(Child, State), {ok, NState}. +do_restart_delay({RestartType, Delay}, Reason, Child, State) -> + case restart1(Child, State) of + {ok, NState} -> + {ok, NState}; + {terminate, NState} -> + _TRef = erlang:send_after(trunc(Delay*1000), self(), + {delayed_restart, + {{RestartType, Delay}, Reason, Child}}), + {ok, state_del_child(Child, NState)} + end. + del_child_and_maybe_shutdown(intrinsic, Child, State) -> {shutdown, state_del_child(Child, State)}; +del_child_and_maybe_shutdown({intrinsic, _Delay}, Child, State) -> + {shutdown, state_del_child(Child, State)}; del_child_and_maybe_shutdown(_, Child, State) -> {ok, state_del_child(Child, State)}. @@ -911,7 +919,8 @@ supname(N,_) -> N. %%% Func is {Mod, Fun, Args} == {atom, atom, list} %%% RestartType is permanent | temporary | transient | %%% intrinsic | {permanent, Delay} | -%%% {transient, Delay} where Delay >= 0 +%%% {transient, Delay} | {intrinsic, Delay} +%% where Delay >= 0 %%% Shutdown = integer() | infinity | brutal_kill %%% ChildType = supervisor | worker %%% Modules = [atom()] | dynamic @@ -962,6 +971,7 @@ validRestartType(temporary) -> true; validRestartType(transient) -> true; validRestartType(intrinsic) -> true; validRestartType({permanent, Delay}) -> validDelay(Delay); +validRestartType({intrinsic, Delay}) -> validDelay(Delay); validRestartType({transient, Delay}) -> validDelay(Delay); validRestartType(RestartType) -> throw({invalid_restart_type, RestartType}). |