[erlang-questions] Timeouted gen_server:call

Dmitry Belyaev rumata-estor@REDACTED
Thu May 13 10:10:46 CEST 2010


This won't help because server may send the message right before timeout 
happens (say 1ms). And client may receive the message right after the 
timeout happens (1ms after).

Mazen Harake wrote:
>
> 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
>
>
> ________________________________________________________________
> erlang-questions (at) erlang.org mailing list.
> See http://www.erlang.org/faq.html
> To unsubscribe; mailto:erlang-questions-unsubscribe@REDACTED
>
>



More information about the erlang-questions mailing list