[erlang-questions] On selective receive (Re: eep: multiple patterns)

Andreas Hillqvist andreas.hillqvist@REDACTED
Wed Jun 4 08:46:39 CEST 2008


As I understand it, the discussion in this thread concerns the process
"default" Message Queue.

What if it would be possible to create Message Queues in addition to
process "default" Message Queue?
Where it would be possible to give options such as:
 * limit to the amount message to store
 * what happens when message queue is full
     * crasch of client/sender and/or server/receiver
     * notification by message
     * block sender (I guess this is not a good idea. Because it is
the opposite to the current semantics of erlangs send.)
 etc...

To suport multiple queues, it would probebly be an idea to extend the
receive statement to accept variables/names to queues:

Q1 = queue:new() % Unamed queue with default options,
                 %similar to a default process queue
Q2 = queue:new(name_of_queue_1, [{size, 3}]),


receive Q1 of
     {msg1, Data} -> do_stuff(Data);
     {msg2, Data} -> do_some_other_stuff(Data)
end,

receive Q1; Q2 of
     {msg1, Data} -> do_stuff(Data);
     {msg2, Data} -> do_some_other_stuff(Data)
end,

Some questions:
Would it solve some of the selective receive problematics?
Would it be allowed a to pass a queue between threeds?
Would it be possible to let more then one process receive messages?


What is your feedback on user defined Message Queues?


Kind regards
Andreas Hillqvist

2008/5/31, Ulf Wiger <ulf@REDACTED>:
> I would really like to discourage people from avoiding
> selective receive because it's "expensive". It can be
> expensive on very large message queues, but this is
> a pretty rare error condition, and fairly easily observable.
>
> (I know of projects that have banned use of selective
> receive for this reason, but without having thought much
> about what to use instead, and when.)
>
> You can use erlang:system_monitor/2 to quickly detect
> if a process is growing memory in a strange way.
>
> An old legacy Ericsson system implemented selective receive
> in a way that the message queue could hold at most 6 messages.
> Any more than that was obviously an error.
>
> I think it might be useful to be able to specify such a limit as
> a spawn option, perhaps together with maximum heap size.
> Exceeding the limit could perhaps lead to the process being
> killed (which might seem backwards in the case of the message
> queue, but at least gives a visible indication), or that the sender
> process would be suspended (which could potentially lead to the
> whole system stopping.)
>
> BR,
> Ulf W
>
> 2008/5/31 Christopher Atkins <christopher316@REDACTED>:
> > Hello, I tried (poorly--I'm a complete novice) to implement a benchmark from
> > your earlier statement.  I didn't do the same thing (load up the message
> > mailbox before consuming them), but what I did write led to a perplexing (to
> > me) discovery.  If I uncomment the line in [loop1/0] below, performance for
> > that loop degrades by an order of magnitude.  Why is that?
> >
> > -module(test_receive).
> > -compile(export_all).
> >
> > start() ->
> >         statistics(runtime),
> >         statistics(wall_clock),
> >         PidLoop1 = spawn(?MODULE, loop1,[]),
> >         sender(PidLoop1, 10000000),
> >         {_, Loop1Time1} = statistics(runtime),
> >         {_, Loop1Time2} = statistics(wall_clock),
> >         io:format("Sent ~p messages in ~p /~p~n", [100000, Loop1Time1,
> > Loop1Time2]),
> >         statistics(runtime),
> >         statistics(wall_clock),
> >         PidLoop2 = spawn(?MODULE, loop2,[]),
> >         sender(PidLoop2, 10000000),
> >         {_, Loop2Time1} = statistics(runtime),
> >         {_, Loop2Time2} = statistics(wall_clock),
> >         io:format("Sent ~p messages in ~p /~p~n", [100000, Loop2Time1,
> > Loop2Time2]).
> >
> > sender(_, 0) -> void;
> > sender(Pid, N) ->
> >         if
> >           N rem 2 =:= 2 ->
> >                 Pid ! test2;
> >           true ->
> >                 Pid ! test1
> >         end,
> >         sender(Pid, N - 1).
> >
> > proc1(F) ->
> >         receive
> >                 start -> spawn_link(F)
> >         end.
> >
> > loop1() ->
> >         receive
> >                 %%test1 -> loop1();
> >                 test2 -> loop1()
> >         end.
> >
> > loop2() ->
> >         receive
> >                 _ -> loop2()
> >         end.
> >
> >
> > ------------------------------------------------------------------------------------------------------------------------------
> > Message: 2
> > Date: Fri, 30 May 2008 18:07:18 +0200
> > From: "Per Melin" <per.melin@REDACTED>
> > Subject: Re: [erlang-questions] eep: multiple patterns
> > To: "Sean Hinde" <sean.hinde@REDACTED>
> > Cc: Erlang Questions <erlang-questions@REDACTED>
> > Message-ID:
> >        <d57f8dd90805300907u44fe7316x2421ab28632cf633@REDACTED>
> > Content-Type: text/plain; charset=ISO-8859-1
> >
> > 2008/5/30 Per Melin <per.melin@REDACTED>:
> >> If I send 100k 'foo' messages and then 100k 'bar' messages to a
> >> process, and then do a catch-all receive until there are no messages
> >> left, that takes 0.03 seconds.
> >>
> >> If I do a selective receive of only the 'bar' messages, it takes 90
> >> seconds.
> >
> > I found my old test code:
> >
> > -module(selective).
> >
> > -export([a/2, c/2]).
> >
> > a(Atom, N) ->
> >    spawn(fun() -> b(Atom, N) end).
> >
> > b(Atom, N) ->
> >    spam_me(foo, N),
> >    spam_me(bar, N),
> >    R = timer:tc(?MODULE, c, [Atom, N]),
> >    io:format("TC: ~p~n", [R]).
> >
> > c(Atom, N) ->
> >    receive
> >        Atom -> c(Atom, N - 1)
> >    after 0 ->
> >        N
> >    end.
> >
> > spam_me(Msg, Copies) ->
> >    lists:foreach(fun(_) -> self() ! Msg end, lists:duplicate(Copies, 0)).
> >
> > ---
> >
> > 2> selective:a(bar, 100000).
> > <0.38.0>
> > TC: {124130689,0}
> > 3> selective:a(foo, 100000).
> > <0.40.0>
> > TC: {23176,0}
> >
> >
> > _______________________________________________
> > erlang-questions mailing list
> > erlang-questions@REDACTED
> > http://www.erlang.org/mailman/listinfo/erlang-questions
> >
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://www.erlang.org/mailman/listinfo/erlang-questions
>



More information about the erlang-questions mailing list