[erlang-questions] Timeouted gen_server:call

Mazen Harake mazen.harake@REDACTED
Thu May 13 08:54:21 CEST 2010


Hi Dmitry,

If the request can become outdated (I.e. the server should ignore it) 
then perhaps you can send the expiry along with the message.

Example:

do_call(Server, MsgId, Msg, Timeout) ->
   try
     gen_server:call(Server, {process, MsgId, Msg, 
calc_expiry_time(Timeout)}, Timeout);
   catch
     exit:{timeout, _} ->
       %% clean up here...
       ok
   end.

implement calc_expirty_time and in the server you simply check if the 
message is old and if so throw it away.

Just a thought,

/Mazen

On 12/05/2010 17:48, Dmitry Belyaev wrote:
> I have a gen_server and many clients. Clients send request to the 
> server with gen_server:call(Server, Msg, Timeout) and when timeout 
> occurs they ask server to abort appropriate reply. But server may 
> reply right before it receives abort message and I may get trash in 
> client's mailbox.
>
> I'm not sure that client can throw away this trash itself. So it is 
> possible for client to fill his message queue with lots of such messages.
>
> I may not let client crash. Neither I don't want to spawn new process 
> for every such request.
>
> Looking through gen module I found that wait_resp*/3 could tell me 
> Mref with exit({timeout, Mref}). Then I could use gen:call() and catch 
> that Mref. But it currently doesn't offer such information.
>
>
> So, I'd like to know how more experienced programmers workaround this 
> problem.
>
>
> Code like this:
>
> -export([do_call/4, handle_call/3, handle_info/2]).
>
> do_call(Server, MsgId, Msg, Timeout) ->
>    try gen_server:call(Server, {process, MsgId, Msg}, Timeout) of
>       Response ->
>          Response
>    catch
>       exit:{timeout, Reason} ->
>          %% this is a place when server can reply us
>          Server ! {abort, MsgId},
>          %% here I'd like to cleanup message queue but I don't know Mref
>          error
>    end.
>
>
> handle_call({process, MsgId, Msg}, From, State) ->
>    start_processing(MsgId, Msg),
>    {noreply, State#state{ids=[{MsgId, From} | State#state.ids]}}.
>
>
> handle_info({ready, MsgId, Response}, State) ->
>    case get_from(MsgId, State) of
>       undefined ->
>          {noreply, State};
>        {From, NewState} ->
>            gen_server:reply(From, Response),
>          {noreply, NewState}
>    end;
>
> handle_info({abort, MsgId}, State) ->
>    case get_from(MsgId, State) of
>       undefined ->
>            {noreply, State};
>       {_, NewState} ->
>          {noreply, NewState}
>    end.
>
>
> ________________________________________________________________
> erlang-questions (at) erlang.org mailing list.
> See http://www.erlang.org/faq.html
> To unsubscribe; mailto:erlang-questions-unsubscribe@REDACTED
>

---------------------------------------------------

---------------------------------------------------

WE'VE CHANGED NAMES!

Since January 1st 2010 Erlang Training and Consulting Ltd. has become ERLANG SOLUTIONS LTD.

www.erlang-solutions.com



More information about the erlang-questions mailing list