Skip to content

Instantly share code, notes, and snippets.

@mweibel
Created February 11, 2015 15:22
Show Gist options
  • Save mweibel/cd859443a2b015d24532 to your computer and use it in GitHub Desktop.
Save mweibel/cd859443a2b015d24532 to your computer and use it in GitHub Desktop.
Supervisor2 MongooseIM vs. rabbit_common
--- apps/ejabberd/src/supervisor2_mongooseim.erl 2015-02-11 12:52:33.000000000 +0100
+++ deps/rabbit_common/src/supervisor2.erl 2015-01-30 07:35:08.000000000 +0100
@@ -23,17 +23,9 @@
%% 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
-%% Delay has passed *and* the MaxT and MaxR parameters allow the
-%% child to be restarted.
-%%
-%% Also note that the Delay is a *minimum*. There is no guarantee
-%% that the child will be restarted within that time, especially if
-%% other processes are dying and being restarted at the same time -
-%% essentially we have to wait for the delay to have passed and for
-%% the MaxT and MaxR parameters to permit the child to be
-%% restarted. This may require waiting for longer than Delay.
+%% Note that if a child is delay-restarted this will reset the
+%% count of restarts towrds MaxR and MaxT. This matters if MaxT >
+%% Delay, since otherwise we would fail to restart after the delay.
%%
%% Sometimes, you may wish for a transient or intrinsic child to
%% exit abnormally so that it gets restarted, but still log
@@ -67,7 +59,7 @@
%%
%% %CopyrightEnd%
%%
--module(supervisor2_mongooseim).
+-module(supervisor2).
-behaviour(gen_server).
@@ -145,7 +137,7 @@
-record(state, {name,
strategy :: strategy(),
children = [] :: [child_rec()],
- dynamics :: ?DICT() | ?SET(),
+ dynamics :: ?DICT:?DICT() | ?SET:?SET(),
intensity :: non_neg_integer(),
period :: pos_integer(),
restarts = [],
@@ -179,6 +171,15 @@
MaxT :: non_neg_integer()},
[ChildSpec :: child_spec()]}}
| ignore.
+-else.
+
+-export([behaviour_info/1]).
+
+behaviour_info(callbacks) ->
+ [{init,1}];
+behaviour_info(_Other) ->
+ undefined.
+
-endif.
-define(restarting(_Pid_), {restarting,_Pid_}).
@@ -680,14 +681,21 @@
handle_info({delayed_restart, {RestartType, Reason, Child}}, State)
when ?is_simple(State) ->
- try_restart(RestartType, Reason, Child, State);
+ try_restart(RestartType, Reason, Child, State#state{restarts = []}); %% [1]
handle_info({delayed_restart, {RestartType, Reason, Child}}, State) ->
case get_child(Child#child.name, State) of
{value, Child1} ->
- try_restart(RestartType, Reason, Child1, State);
+ try_restart(RestartType, Reason, Child1,
+ State#state{restarts = []}); %% [1]
_What ->
{noreply, State}
end;
+%% [1] When we receive a delayed_restart message we want to reset the
+%% restarts field since otherwise the MaxT might not have elapsed and
+%% we would just delay again and again. Since a common use of the
+%% delayed restart feature is for MaxR = 1, MaxT = some huge number
+%% (so that we don't end up bouncing around in non-delayed restarts)
+%% this is important.
handle_info(Msg, State) ->
error_logger:error_msg("Supervisor received unexpected message: ~p~n",
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment