[erlang-questions] Fwd: Message Receive Semantics (was eep:MultiplePatterns)
Jay Nelson
jay@REDACTED
Tue Jun 3 17:47:26 CEST 2008
Valentin accidentally replied directly to me:
> From: "Valentin Micic" <valentin@REDACTED>
> Date: June 2, 2008 12:02:15 AM PDT
> To: "Jay Nelson" <jay@REDACTED>
> Subject: Re: [erlang-questions] Message Receive Semantics (was
> eep:MultiplePatterns)
>
> Hi Jay,
>
> Back in 2000, when I just started with Erlang (had a extensive
> commercial experience in procedural languages, though), one of the
> first problems I tried to solve had to do with priority handling.
> So I wrote something very ugly, but someting that reflected a
> paridgm I had at the time -- I remember writing something like this:
>
> loop_high( 0 ) -> loop_normal( 3 );
> loop_high( N ) ->
> receive
> {high, Msg} ->
> process_msg( Msg ),
> loop_high( N-1 )
> after 0 -> receive
> {normal, Msg}->
> process_msg( Msg ),
> loop_high( N )
> after 0 -> receive
> { low, Msg} ->
> process_msg( Msg ),
> loop_high( N )
> after 0 -> receive
> ANY ->
> case process_msg( ANY ) of
> stop -> exit( normal );
> _ -> loop_high( N )
> end
> after 250 -> loop_high( N )
> end
> end
> end
> end .
> loop_normal( 0 ) -> loop_low( 1 );
> loop_normal( N ) ->
> recevie
> {low, Msg} ->
> process_msg( Msg ),
> loop_normal( N-1 )
> after 0 -> receive
> {high, Msg} ->
> process_msg( Msg ),
> loop_normal( N )
> after 0 -> ...
> ....
> ....
> end
> end .
> loop_low( 0 ) -> loop_high( 5 );
> loop_low( N ) -> ...
> ...
> ...
>
> The above code would do the trick, however, being ugly as it may --
> would eventually trigger refactoring to the tune of:
>
> loop_high( 0 ) -> loop_normal( 3 );
> loop_hihg(N) ->
> receive
> {high, Msg} ->
> process_msg( Msg ),
> loop_high( N-1 );
> {normal, Msg} ->
> process_msg( Msg ),
> loop_high( N );
> {low, Msg} ->
> process_msg( Msg ),
> loop_high(N);
> ANY ->
> case process_msg( ANY ) of
> stop -> exit( normal );
> _ -> loop_high( N )
> end
> after 1000 -> loop_high( N )
> end.
> loop_normal( 0 ) -> loop_low( 1 );
> loop_normal(N) ->
> receive
> {normal, Msg} ->
> process_msg( Msg ),
> loop_normal(N-1);
> {high, Msg} ->
> process_msg( Msg ),
> loop_normal( N);
> {low, Msg} ->
> process_msg( Msg ),
> loop_normal(N);
> ANY ->
> case process_msg( ANY ) of
> stop -> exit( normal );
> _ -> loop_normal( N )
> end
> after 1000 -> loop_normal( N )
> end.
> loop_low( 0 ) -> loop_high( 5 );
> loop_low(N ) -> .....
> ....
> ....
>
> What I'm trying to say, I guess -- it does not really matter if one
> is novice or not. We all know how to think, and only through
> thinking we can arrive to a point where we could articulate the
> "right" kind of questions. Nothing wrong in making a few mistakes
> in a process.
>
> BTW, how easy one may make a mistake depends largely on how the
> problem was stated. If one says:
>
>
>
> 3) Always handle messages in the following order:
> a) 5 messages of {reply, high, Msg}
> b) 3 messages of {reply, normal, Msg}
> c) 1 message of {reply, low, Msg}
> d) 'EXIT' message
>
>
>
> one should not get surprised if the resulting code blocks until 5
> high priority messages have been processed. However, if one
> indicates that preference should be given to high priority
> messages, than normal, followed by low priority message, utilising
> a ratio of 5:3:1, and stipulate that should there be no higher
> priority message, lower one should be processed -- one may close a
> semantic gap, and thus prevent a novice from making a mistake. All
> of that in far better English, of course ;-).
>
>
> V.
>
> ----- Original Message ----- From: "Jay Nelson" <jay@REDACTED>
> To: <erlang-questions@REDACTED>
> Sent: Monday, June 02, 2008 1:08 AM
> Subject: Re: [erlang-questions] Message Receive Semantics (was
> eep:MultiplePatterns)
>
>
>> Valentin wrote:
>>
>> > Consider a following scenario: for every five "high" priority
>> messages
>> > processed, I wanted to handle three "normal" and one "low" priority
>> > message(*). To implement this with a selective receive is
>> relatively easy
>> > and concise, even for a novice programmer. To do without it, may be
>> > considerably more difficult and messy.
>>
>>
>> I think priority is one of the harder cases to get right, actually.
>> The beginner
>> will end up blocked waiting for the 5th high priority message when
>> only
>> 4 are on the queue, or will end up delaying high priority messages
>> while
>> they scan for low priority ones.
>>
>> So here is the concrete challenge:
>>
>> 1) Send a message to a linked process:
>> a) {request, Msg}
>> 2) The other process should generate 20 or so messages randomly
>> and then quit
>> 3) Always handle messages in the following order:
>> a) 5 messages of {reply, high, Msg}
>> b) 3 messages of {reply, normal, Msg}
>> c) 1 message of {reply, low, Msg}
>> d) 'EXIT' message
>>
>> Of course, there may not be 5 remaining high messages or 3 remaining
>> normal messages so you need to deal with these end cases. In
>> doing so,
>> make sure you don't just end up polling every 100 milliseconds. I've
>> simplified the problem by only having one process that can generate
>> replies, so that the selective receive doesn't become even more
>> complicated.
>>
>> I challenge any beginner or intermediate erlang programmer to write
>> and post the code for both processes and a description of your
>> results.
>> All the advanced erlang people can help point out the issues that
>> will
>> have to be addressed when you change the initial code approach.
>>
>> At least, that is my bet. Valentin may be right. Let's see some
>> code!
>> In another post, I'll give an alternative problem that is easier and
>> shows the usefulness of selective receive.
>>
>> In general, I would argue that erlang's approach to message is geared
>> towards handling multiple conversations or sessions on a single
>> channel,
>> and that handling priorities is a pathological case for the simple
>> message
>> queue approach that erlang uses. It is far easier to implement
>> priorities
>> by unloading the whole queue into a process which implements a
>> priority
>> queue and then doling out messages according to your own priority
>> logic.
>>
>> jay
>>
>> _______________________________________________
>> erlang-questions mailing list
>> erlang-questions@REDACTED
>> http://www.erlang.org/mailman/listinfo/erlang-questions
>
More information about the erlang-questions
mailing list