[erlang-questions] "simple_one_for_one" supervisor childs termination problem

22 views
Skip to first unread message

zabrane Mikael

unread,
Nov 30, 2010, 5:58:40 AM11/30/10
to Erlang Questions Mailinglist
Hi everybody,

I'm testing a "simple_one_for_one" supervisor (foo_sup.erl) to
supervise a bunch of workers (foo_srv.erl implemented as gen_server).
On the top of that, there's an application process (foo_app.erl) which
let me start/stop the entire application easily.
Everything went fine except the termination.

When calling "application:stop(foo_app)", the workers never get their
"terminate/2" function called.

Here's my supervisor (foo_sup.erl) init/1 function:
init([]) ->
AChild = {foo_srv, {foo_srv, start_link, []},
transient, 180000, worker, [foo_srv]},
Strategy = {simple_one_for_one, 10, 100},
{ok, {Strategy, [AChild]}}.


Any help will be very appreciated!


N.B: it seems to me that the Erlang doc is also missing the fact the
atom 'infinity'
couldn't be use with simple_one_for_one. Am I right? So in this
example, I'm using a kill timeout of 3 minutes (18000).

--
Regards
Zabrane

________________________________________________________________
erlang-questions (at) erlang.org mailing list.
See http://www.erlang.org/faq.html
To unsubscribe; mailto:erlang-questio...@erlang.org

Lukas Larsson

unread,
Nov 30, 2010, 6:09:56 AM11/30/10
to zabrane Mikael, Erlang Questions Mailinglist
When terminating a child the supervisor calls exit(Pid,shutdown). When a
process receives an exit signal it will automatically die unless it is
trapping exits. So in order for terminate to be called before the process
dies you have to trap exits within the child process.

This is described in the gen_server Design Principles documentation:
http://www.erlang.org/doc/design_principles/gen_server_concepts.html#id62546

Lukas

Matthew Sackman

unread,
Nov 30, 2010, 6:26:01 AM11/30/10
to erlang-q...@erlang.org
On Tue, Nov 30, 2010 at 12:09:56PM +0100, Lukas Larsson wrote:
> When terminating a child the supervisor calls exit(Pid,shutdown). When a
> process receives an exit signal it will automatically die unless it is
> trapping exits. So in order for terminate to be called before the process
> dies you have to trap exits within the child process.

Yeah, but trapping exits is not normally a good idea. Zabrane probably
wants to use Rabbit's supervisor2 [0] which adds
simple_one_for_one_terminate which is the same as simple_one_for_one
except children are killed off as per the indicated shutdown spec (see
man supervisor).

[0] http://hg.rabbitmq.com/rabbitmq-server/file/default/src/supervisor2.erl

Matthew

zabrane Mikael

unread,
Nov 30, 2010, 7:40:09 AM11/30/10
to Lukas Larsson, Erlang Questions Mailinglist
Hi Lucas,

2010/11/30 Lukas Larsson <gara...@gmail.com>:


> When terminating a child the supervisor calls exit(Pid,shutdown). When a
> process receives an exit signal it will automatically die unless it is
> trapping exits. So in order for terminate to be called before the process
> dies you have to trap exits within the child process.

I forgot to mention that I'm already traping exit in "foo_srv.erl":
%% --- gen server callbacks
init(Args) ->
process_flag(trap_exit, true),
{ok, Args}.

Even with that, the worker process never get the "shutdown" EXIT message.

zabrane Mikael

unread,
Nov 30, 2010, 7:42:17 AM11/30/10
to erlang-q...@erlang.org
Hi Matthew,

> Yeah, but trapping exits is not normally a good idea. Zabrane probably
> wants to use Rabbit's supervisor2 [0] which adds
> simple_one_for_one_terminate which is the same as simple_one_for_one
> except children are killed off as per the indicated shutdown spec (see
> man supervisor).
>
> [0] http://hg.rabbitmq.com/rabbitmq-server/file/default/src/supervisor2.erl

I'll give this a try as I'm already using "gen_server2" (from RabbitMQ).

Thanks for the pointer.

--
Regards
Zabrane

Matthew Sackman

unread,
Nov 30, 2010, 7:59:31 AM11/30/10
to erlang-q...@erlang.org
On Tue, Nov 30, 2010 at 01:40:09PM +0100, zabrane Mikael wrote:
> I forgot to mention that I'm already traping exit in "foo_srv.erl":
> %% --- gen server callbacks
> init(Args) ->
> process_flag(trap_exit, true),
> {ok, Args}.
>
> Even with that, the worker process never get the "shutdown" EXIT message.

That's odd then. That should only happen if there's a
brutal_kill/exit(kill) going on.

Matthew

zabrane Mikael

unread,
Nov 30, 2010, 8:02:01 AM11/30/10
to erlang-q...@erlang.org
Yep

zabrane Mikael

unread,
Nov 30, 2010, 8:05:44 AM11/30/10
to erlang-q...@erlang.org
Hi Matthew,

It works like a charm with supervisor2.
You save my day ;-) Thousand thanks.

--
Regards
Zabrane

2010/11/30 Matthew Sackman <mat...@wellquite.org>:

Lukas Larsson

unread,
Nov 30, 2010, 8:14:24 AM11/30/10
to zabrane Mikael, erlang-q...@erlang.org
might be gen_server2 which does not play nice with supervisor, using OTP's
supervisor and gen_server the terminate call works as it should.

Lukas

Matthew Sackman

unread,
Nov 30, 2010, 8:14:18 AM11/30/10
to zabrane Mikael, erlang-q...@erlang.org
Hi Zabrane,

On Tue, Nov 30, 2010 at 02:05:44PM +0100, zabrane Mikael wrote:
> It works like a charm with supervisor2.
> You save my day ;-) Thousand thanks.

Glad it works. I'm sure over time we'll likely end up
replacing/rewriting most of the stdlib and OTP framework ;)

Matthew Sackman

unread,
Nov 30, 2010, 8:16:41 AM11/30/10
to erlang-q...@erlang.org
On Tue, Nov 30, 2010 at 02:14:24PM +0100, Lukas Larsson wrote:
> might be gen_server2 which does not play nice with supervisor, using OTP's
> supervisor and gen_server the terminate call works as it should.

Not impossible - we've found bugs in gs2 before. If Zabrane can post the
code he's using I can certainly take a look at that.

zabrane Mikael

unread,
Nov 30, 2010, 8:20:07 AM11/30/10
to Lukas Larsson, erlang-q...@erlang.org
Maybe that's the reason. Anyway, I'm pretty happy with gen_server2 as
we're using it for a while in production (we moved all our code from gen_server
togen_server2).

Thanks Lukas

--
Regards
Zabrane


2010/11/30 Lukas Larsson <gara...@gmail.com>:

zabrane Mikael

unread,
Nov 30, 2010, 8:20:44 AM11/30/10
to zabrane Mikael, erlang-q...@erlang.org
;-)

2010/11/30 Matthew Sackman <mat...@wellquite.org>:


> Hi Zabrane,
>
> On Tue, Nov 30, 2010 at 02:05:44PM +0100, zabrane Mikael wrote:
>> It works like a charm with supervisor2.
>> You save my day ;-) Thousand thanks.
>
> Glad it works. I'm sure over time we'll likely end up
> replacing/rewriting most of the stdlib and OTP framework ;)
>
> Matthew
>

--
Regards
Zabrane

zabrane Mikael

unread,
Nov 30, 2010, 8:38:48 AM11/30/10
to erlang-q...@erlang.org
Sorry, that's a closed source code!

--
Regards
Zabrane

2010/11/30 Matthew Sackman <mat...@wellquite.org>:

Mazen Harake

unread,
Nov 30, 2010, 8:48:02 AM11/30/10
to zabrane Mikael, erlang-q...@erlang.org
Just out of curiousity, what does gen_server2 bring to the table?

/M

On 30/11/2010 15:20, zabrane Mikael wrote:
> Maybe that's the reason. Anyway, I'm pretty happy with gen_server2 as
> we're using it for a while in production (we moved all our code from gen_server
> togen_server2).
>
> Thanks Lukas
>

Matthew Sackman

unread,
Nov 30, 2010, 8:47:26 AM11/30/10
to erlang-q...@erlang.org
On Tue, Nov 30, 2010 at 03:48:02PM +0200, Mazen Harake wrote:
> Just out of curiousity, what does gen_server2 bring to the table?

Please read the documentation at the top of it:
http://hg.rabbitmq.com/rabbitmq-server/file/default/src/gen_server2.erl

Some of the points (eg point 2) are now taken care of (since R14)
directly in Erlang. However, we still support Rabbit back to R12B5 so we
can't rely on that just yet.

Matthew

Reply all
Reply to author
Forward
0 new messages