[erlang-questions] gen_server call and reply (Matthias Lang)

Ingela Anderton Andin ingela@REDACTED
Tue Sep 18 08:27:49 CEST 2007

erlang-questions-request@REDACTED wrote:
> Why use 'noreply'? I can only really think of one reason---you have a
> relatively long-running request but don't want to block the gen_server
> while it runs. Maybe there's also some case where you can avoid a
> deadlock, but I haven't thought about that.
I use noreply  quite often.  One reason  is that I do not want my server to
do blocking receives as that will spoil the soft upgrade for that process.
I almost always use active_once on a socket to collect arbitary number 
of  bytes in my server
and then returning the response to the client with gen_server:reply/2 
when I got the needed amount.  (Could also be gen_fsm:reply/2).

> In the case of the long-running request, what I do instead is
>   {reply, {pending, Ref}, State}
> where Ref is a reference which is then included in a later message
> sent the old-fashioned way. This amounts to more or less the same as
> 'noreply', though it's one message more expensive and has the benefit
> of making it easier to reason about timeouts, at least to my mind.
I do not agree.  That changes the  semantics for the client. I think a 
client that
does a call shall hang until the reply is delivered (or is timed out)  
that is the semantics of call otherwise you might as well use cast.  Of 
course  for a long running request you do not want the server to hang 
for the duration of the call and that is one of the  reasons why 
gen_server:reply/2  exists. If it is an independent calculation the best 
option is to spawn a new process that does the calculation and then 
calls gen:server_reply/2 in the new process.  Otherwise you
save "From" in the state and send the reply sometime later when you got 
enough information from
elsewhere to send the reply. Timeout can always be handled with the help 
of erlang:send_after.

Regards Ingela - OTP team

More information about the erlang-questions mailing list