Erlang/OTP Forums

Author Message

<  Erlang questions mailing list  ~  Timeouted gen_server:call

Guest
Posted: Wed May 12, 2010 3:28 pm Reply with quote
Guest
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@erlang.org

Post received from mailinglist
Spectra
Posted: Wed May 12, 2010 11:23 pm Reply with quote
User Joined: 08 Dec 2008 Posts: 56 Location: Australia
On 13/05/10 00: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.
>
Why can't the client clean up its queue itself? A general rule of
thumb, in my experience at least, is that processes should flush their
message queue of any "unexpected" messages - if not all the time, at
least regularly. Not because they /should/ expect to get them, but
because you don't want them to misbehave if they do (you're right to be
concerned about a growing queue - as several people on this list, myself
included, have discovered it can be "bad" when a queue gets too big).
In the case of a gen_server and similar, this is easy - just add a
catch-all

handle_info(_, State) -> {noreply, State}

In the case of non "gen style" code, just make sure it regularly reaches
and loops on a 'receive' block which has a clause which matches
everything you're not interested in and discards it.

Cheers,

Bernard

________________________________________________________________
erlang-questions (at) erlang.org mailing list.
See http://www.erlang.org/faq.html
To unsubscribe; mailto:erlang-questions-unsubscribe@erlang.org

Post received from mailinglist
View user's profile Send private message
Guest
Posted: Thu May 13, 2010 6:56 am Reply with quote
Guest
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@erlang.org
>

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

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

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@erlang.org

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

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

WE'VE CHANGED NAMES!

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

www.erlang-solutions.com

Post received from mailinglist
Guest
Posted: Thu May 13, 2010 8:12 am Reply with quote
Guest
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@erlang.org
>>
>
> ---------------------------------------------------
>
> ---------------------------------------------------
>
> 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@erlang.org
>
>


________________________________________________________________
erlang-questions (at) erlang.org mailing list.
See http://www.erlang.org/faq.html
To unsubscribe; mailto:erlang-questions-unsubscribe@erlang.org

Post received from mailinglist
wuji
Posted: Mon Aug 20, 2012 7:37 am Reply with quote
User Joined: 10 Aug 2012 Posts: 654
a link to go to Netflix, you would wind up up jordan 6 up at "BudgetMatch," according to the FBI. The practice is
"click hijacking."Once the FBI got around to fixing the problem problem [h4]cheap jordans[/h4] problem in 2011, it realized it couldn't simply shut down
rogue servers because infected computers would be left without a a cheap replica *beep* a functioning DNS, leaving them virtually Internet-less. So it set
temporary servers to give malware-infected Internet users time to fix fix jordan 6 fix their computers.And time runs out on Monday, July 9.(There
a planned attack this Monday that will shut down the the imitation designer *beep* the Internet; those whose computers are already infected will lose
Band-Aid the FBI put on the problem more than a a knockoff designer *beep* a year ago.)Who Is Affected?Initially, there were more than 4
infected computers in 100 countries, including 500,000 in the United United jordan 6s United States, according to the indictment.As of July 4, there
View user's profile Send private message

Display posts from previous:  

All times are GMT
Page 1 of 1
This forum is locked: you cannot post, reply to, or edit topics.

Jump to:  

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum