gen_server:selective_receive/1
Ulf Wiger
etxuwig@REDACTED
Tue Jan 28 14:25:57 CET 2003
On Tue, 28 Jan 2003, Per Bergqvist wrote:
>Except that the tag is changed from '$gen_cast' to 'cast'
>etc. isn't this equivalent to a receive ... after 0 ?
>
>/Per
OK, to follow up on the idea a step further, below's an
implementation that actually works.
The following code was written to test the new
implementation (in a gen_server callback):
handle_call(start_test, From, State) ->
timer:sleep(3000),
Reply = timer:tc(
gen_server,fold_messages,
[
fun({cast, _} = Msg, Acc) ->
{true, [Msg|Acc]};
(Msg, Acc) ->
false
end, []]),
{reply, Reply, State}.
Basically gen_server:fold_messages(Fun, Acc), where
Fun(Msg, Acc) should return {true, Acc1} or false (in the
former case, the message is consumed, in the latter, not),
had the following performance on my machine:
# msgs in the queue exec. time (us)
10 6.5
100 300
1,000 3,000
10,000 40,000
The cost is, I think, reasonable. Still, after having gotten
some sleep, I've decided that it doesn't solve the problem.
It just reduces it (possibly creating other problems in the
process.) The real problem is one of serialization, and
cannot be addressed this way. I withdraw my suggestion. Bad
idea.
/Uffe
fold_messages(Fun, Acc) ->
{_, Messages} = process_info(self(), messages),
Parent = get_parent(),
fold(Messages, Fun, Acc, Parent).
fold([{'$gen_call',From,Request} = X|Rest], Fun, Acc, Parent) ->
fold_one({call,From,Request}, X, Fun, Acc, Rest, Parent);
fold([{'$gen_cast',Msg} = X|Rest], Fun, Acc, Parent) ->
fold_one({cast, Msg}, X, Fun, Acc, Rest, Parent);
fold([{'EXIT',Pid,Why} = X|Rest], Fun, Acc, Parent) when Pid /= Parent ->
fold_one(X, X, Fun, Acc, Rest, Parent);
fold([Msg|Rest], Fun, Acc, Parent) when size(Msg) == 6,
element(1,Msg) == system ->
%% ignore
fold(Rest, Fun, Acc, Parent);
fold([Msg|Rest], Fun, Acc, Parent) ->
fold_one({info, Msg}, Msg, Fun, Acc, Rest, Parent);
fold([], _, Acc, _) ->
Acc.
fold_one(Msg, X, Fun, Acc, Rest, Parent) ->
NewAcc = case Fun(Msg, Acc) of
{true, Acc1} ->
%% consume the message
receive X -> X end,
Acc1;
false ->
Acc
end,
fold(Rest, Fun, NewAcc, Parent).
--
Ulf Wiger, Senior Specialist,
/ / / Architecture & Design of Carrier-Class Software
/ / / Strategic Product & System Management
/ / / Ericsson Telecom AB, ATM Multiservice Networks
More information about the erlang-questions
mailing list