[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