'after' in gen_server

Rick Pettit rpettit@REDACTED
Fri Mar 24 04:01:11 CET 2006


On Thu, Mar 23, 2006 at 08:59:45PM -0500, orbitz@REDACTED wrote:
> The only problem I have with that is it sounds very error prone.  What 
> if I forget a timeout?  The more callbacks i implement the uglier it'll 
> get, won't it?

The way I see it you have two options:

  1) Use the gen_server behaviour and its timeout mechanism--this involves
     returning an additional timeout parameter from:

       Module:init/1
       Module:handle_call/3
       Module:handle_cast/2
       Module:handle_info/2

     You will service the idle timeout in Module:handle_info/2. This is pretty
     simple, IMO, but I agree it is overkill if you don't otherwise require a
     gen_server.

  2) Don't use gen_server (or any OTP behaviour)--rewrite your process as
     a simple server with receive loop. Now that you have direct access to
     the receive loop, you can plug in your 'after' clause with idle timeout
     and deal with the server going idle there.

If you insist on using a gen_server than I can't see the point in not going
with (1)--anything else is going to require more server state, more code, and
will ultimately be more error prone.

-Rick

> On Mar 23, 2006, at 4:35 PM, Rick Pettit wrote:
> 
> >On Thu, Mar 23, 2006 at 04:26:22PM -0500, orbitz@REDACTED wrote:
> >>I want to do it from all callbacks.  Basically I want to make it so if
> >>the server is idle for X amount of time, then that means something is
> >>wrong and I need to do something to figure out what is wrong.
> >
> >Then have your callbacks set a gen_server "idle timeout" by way of the
> >gen_server timeout mechanism, and service timeouts in handle_info/2.
> >
> >It is as simple as passing a timeout value in the return value from 
> >your
> >callbacks--Module:init/1, Module:handle_call/3, Module:handle_cast/2, 
> >etc.
> >
> >-Rick
> >
> >>On Mar 23, 2006, at 11:04 AM, Rick Pettit wrote:
> >>
> >>>On Thu, Mar 23, 2006 at 10:42:04AM -0500, orbitz@REDACTED wrote:
> >>>>I am reworking a bit of code into gen_server pattern.  In this code 
> >>>>I
> >>>>have a typical loop construct.  In this I want to perform an action 
> >>>>if
> >>>>no messages have been receive in a certain amount of time, to do 
> >>>>this
> >>>>I
> >>>>simply have after sometimeout ->.  Is there any equivalence of this 
> >>>>in
> >>>>gen_server?
> >>>
> >>>If I understand you correctly, all you need to do is set a timeout 
> >>>when
> >>>returning from one of the gen_server callback functions.
> >>>
> >>>For example, instead of returning {ok,State} from Module:init/1, 
> >>>return
> >>>{ok,State,TimeoutMs}. You can do this for all the gen_server callback
> >>>routines (at least handle_call/handle_cast, etc).
> >>>
> >>>This effectively sets a timer which will expire if no message is
> >>>received
> >>>by the gen_server before TimeoutMs has elapsed. If/when the timer 
> >>>does
> >>>expire, you receive a 'timeout' message in Module:handle_info/2.
> >>>
> >>>-Rick
> >>>
> >>>P.S. Since gen_server abstracts the server receive loop, I (as a
> >>>general rule
> >>>    of thumb) *never* call receive in a gen_server callback module.
> >>>
> >>>>It has been suggested that I use a timer and record when the last
> >>>>message has come in and when the timer signals check against that
> >>>>message.  This seems a poor solution.  Another suggestions was to 
> >>>>use
> >>>>a
> >>>>gen_fsm with a timeout, but this seem a bit much just to get an
> >>>>'after'
> >>>>mechanism. Any other suggestions?  Perhaps my disregard of gen_fsm 
> >>>>is
> >>>>a
> >>>>bit hasty?
> >>>
> >>
> >
> 



More information about the erlang-questions mailing list