[erlang-questions] Shutting down a gen_server in a supervision tree
Jeroen Koops
koops.j@REDACTED
Fri Jun 5 09:49:40 CEST 2009
I just discovered application:prep_stop. That looks like it's going to be of
help.
On Fri, Jun 5, 2009 at 9:47 AM, Jeroen Koops <koops.j@REDACTED> wrote:
> Hi Torben,
>
> > 1. Why is it important for your to keep the network connection happy when
> you are shutting down?
>
> For some protocols, it is important that the connection is shut down in an
> orderly manner, instead of just closing the TCP connection. As an example,
> closing an SMPP connection involves first waiting for responses to
> oustanding requests, sending a logout PDU and waiting for a logout response
> PDU.
> Failing to wait for responses to outstanding requests means you don't know
> if certain requests have been accepted by the server. Failing to send the
> logout PDU may lead to the server not realizing that you have logged out and
> rejecting new login attempts for some time.
>
> > 2. When you are being told to die you should only clean up your
> resources. Pending messages should not be a concern. If the requests are so
> important you should consider spawning a separate process for them.
>
> That's a possibility, but not what I want - I want
> application:stop(my_application) to finish only after everything has been
> shut down cleanly. Leaving a new process hanging around handling closing the
> connection is not really an option.
>
> > 3. Your problem sounds more like a gen_fsm problem where you should
> introduce a shutting_down state that collects responeses or times out.
>
> May gen_fsm is more fitting here than a gen_server, but I don't think it
> will make a huge difference. If I create an extra shutting_down state (which
> can be done just as easy with a gen_server by setting some flag in the
> gen_server's state, by the way), someone will still have to trigger this
> state.
>
> > 4. My code style is normally to let the supervisors help out with
> starting of processes and try to restart according to the policies. Shutting
> down is normally something for another worker process to instruct us to do.
>
> So you don't use application:stop/1 for this?
>
> Regards,
>
> Jeroen
>
>
>
>
> On Thu, Jun 4, 2009 at 10:00 PM, Torben Hoffmann <
> torben.lehoff@REDACTED> wrote:
>
>> Some questions/observations to get the right context:
>>
>> 1. Why is it important for your to keep the network connection happy
>> when you are shutting down?
>> 2. When you are being told to die you should only clean up your
>> resources. Pending messages should not be a concern. If the requests are so
>> important you should consider spawning a separate process for them.
>> 3. Your problem sounds more like a gen_fsm problem where you should
>> introduce a shutting_down state that collects responeses or times out.
>> 4. My code style is normally to let the supervisors help out with
>> starting of processes and try to restart according to the policies. Shutting
>> down is normally something for another worker process to instruct us to do.
>>
>> Sorry if I did not get my interpretation of your problem right .
>>
>> Cheers,
>> Torben
>>
>>
>> On Thu, Jun 4, 2009 at 2:11 PM, Jeroen Koops <koops.j@REDACTED> wrote:
>>
>>> 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