Shutting down a gen_server in a supervision tree

Jeroen Koops koops.j@REDACTED
Thu Jun 4 14:11:23 CEST 2009


Hi all,

I'm puzzled by the following: I have a gen_server that is part of an
application. The gen_server maintains a network connection using some
request/response protocol. When shutting down, it is important that the
gen_server wait for responses to all outstanding requests (or timeouts)
before terminating. To realize this, I would like the gen_server to keep
operating normally - that is, being able to handle_call/3, handle_cast/2 and
handle_info/2 - between the time the supervisor sends the { 'EXIT', shutdown
} message, and the moment the gen_server really terminates.

I thought this was simply a matter of:
- Specifying some integer value > 0 as the Shutdown value in the
supervisor's child-specification
- Setting trap_exit to true in the gen_server's init function
- Handling the { 'EXIT', shutdown } message from the supervisor in the
handle_info/2 function. The only thing this would do is setting some flag in
the gen_server's internal state, indicating that we are now in the process
of shutting down.
- When the time has come to really shut down (so after all outstanding
requests have been responded to, or timed out), respond with { stop,
shutdown, SomeReply, SomeState } from a handle_call/3 or with { stop,
shutdown, SomeState } from a handle_cast/2 or handle_info/2, which would
send an exit-message back to the supervisor indicating that we have
terminated.

Unfortunately, this doesn't seem to work. What seems to happen instead is
for the { 'EXIT', shutdown } message to immediately trigger a call to the
gen_server's terminate function- handle_info/2 is never called.
In theory, I could of course set up a receive-loop in the terminate function
and deal with incoming messages in that way, but that would mean I would
process incoming messages (data from a TCP connection, for example) in two
different ways: by implementing handle_info before the shutdown, and by
explicitly receiving message after shutdown.

How is this normally handled?

Thanks,

Jeroen


More information about the erlang-questions mailing list