[erlang-questions] non-FIFO behavior in process mailboxes?

35 views
Skip to first unread message

Michael Turner

unread,
Apr 22, 2012, 12:25:21 PM4/22/12
to erlang-q...@erlang.org
When the code listed below executes with the first io:format call
commented out, it breaks, reporting:

** exception error: no match of right hand side value []
in function wg:init/0

When I don't have it commented out, it works (sort of), writing

val_for (P)=[]
val_for (P)=2
ok

Here's the code:
-----

-module(wg).
-export ([init/0, be/2]).

val_for (P) ->
P ! {tell, self(), val},
receive
{Val, for, P} -> Val
end.

be (Arg, Val) ->
receive
[H|T] ->
self() ! T,
self() ! H,
be (Arg, Val);
[] ->
be (Arg, Val);
{tell, X, val} ->
X ! {Val, for, self()},
be (Arg, Val);
{set_arg_to, A} ->
be (A, Val);
{set_val_to, V} ->
be (Arg, V)
end.

init() ->
P = spawn (wg, be, [[],[]]),
P ! [{set_arg_to, 1}, {set_val_to, 2}],
% io:format ("val_for (P)=~p~n", [val_for (P)]),
2 = val_for (P),
io:format ("val_for (P)=~p~n", [val_for (P)]),
ok.
-----

This is R14B on Windows XP. Haven't tried it elsewhere yet.

Seeing this really messes with my mental model of process mailboxes.
With the first io:format call commented out, I think process P should
be seeing messages queued up in the following order:

[{set_arg_to, 1}, {set_val_to, 2}]
[{set_val_to, 2}]
{set_arg_to, 1}
[]
{set_val_to, 2}
{tell, X, val}

And shouldn't this mean that Val = 2 in process P when the {tell, X,
val} message reaches P? As I interpret Armstrong pp.145-6, since
matches are guaranteed in this case, there's no save queue activity;
since there's no "after" close, the timer is irrelevant; so you should
get pure FIFO behavior, right?

-michael turner
_______________________________________________
erlang-questions mailing list
erlang-q...@erlang.org
http://erlang.org/mailman/listinfo/erlang-questions

Ulf Wiger

unread,
Apr 22, 2012, 1:23:40 PM4/22/12
to Michael Turner, erlang-q...@erlang.org
You seem to have a race between the messages sent from the client and the ones the server sends to itself.

Bear in mind that the client doesn't yield after send, add SMP to the mix and you cannot know whether that server consumes the first message before the client sends its

BR,
Ulf W

Ulf Wiger, Feuerlabs, Inc.
http://www.feuerlabs.com

Ulf Wiger

unread,
Apr 22, 2012, 1:27:26 PM4/22/12
to Ulf Wiger, erlang-q...@erlang.org
Oh, and the io:format/2 call _does_ force a yield, since it involves a synchronous call to the group_leader.

BR,
Ulf W

Ulf Wiger, Feuerlabs, Inc.
http://www.feuerlabs.com

Michael Turner

unread,
Apr 22, 2012, 11:38:28 PM4/22/12
to Ulf Wiger, erlang-q...@erlang.org
On Mon, Apr 23, 2012 at 2:23 AM, Ulf Wiger <u...@feuerlabs.com> wrote:
> You seem to have a race between the messages sent from the client and the ones the server sends to itself.

That, I could see. What I couldn't see was how. But it came to me when
my head hit the pillow. (Which was, naturally, shortly after I sent
e-mail to the list about it.) Sometimes, when I'm tired, I fall into
an old mindset that apparently derives from the days of writing
interrupt service routines running at high processor priority back in
the 1980s. And even *that's* not a good excuse in this case.

> Bear in mind that the client doesn't yield after send, add SMP to the mix and you cannot know whether that server consumes the first message before the client sends its
>
> BR,

Before the client sends its ... BR? "Best Regards"? After a delay? Oh,
*that's* what I forgot to do! ;-)

This bug came out of experimentation inspired by the recent discussion
of initializing objects *after* their creation, a topic raised by
Richard O'Keefe. And -- waddya know -- the problem here relates
directly to his objection to this practice: inconsistent intermediate
states. It appears that when you model your objects as processes, the
danger is particularly acute.

Lesson learned. Message ... received.

-michael turner

Ulf Wiger

unread,
Apr 23, 2012, 1:36:38 AM4/23/12
to Michael Turner, erlang-q...@erlang.org

On 23 Apr 2012, at 05:38, Michael Turner wrote:

> Before the client sends its ... BR? "Best Regards"? After a delay? Oh,
> *that's* what I forgot to do! ;-)

Uhm… yes, processes should be well-behaved. :)

> This bug came out of experimentation inspired by the recent discussion
> of initializing objects *after* their creation, a topic raised by
> Richard O'Keefe. And -- waddya know -- the problem here relates
> directly to his objection to this practice: inconsistent intermediate
> states. It appears that when you model your objects as processes, the
> danger is particularly acute.

For this reason, there is the gen_server:enter_loop(), which basically
(for one thing) allows you to stay in a protected state after init().

Also, plain_fsm:start_opt(Mod, InitF, …) allows you to have the InitF
return {reply, {ok, self()}, Cont}, where Cont is a continuation function
that let's the process proceed - possibly in a protected state.

BR,
Ulf

Ulf Wiger, Co-founder & Developer Advocate, Feuerlabs Inc.
http://feuerlabs.com

David Mercer

unread,
Apr 27, 2012, 3:26:38 PM4/27/12
to Michael Turner, erlang-q...@erlang.org
On Apr 22, 2012, at 20:38, Michael Turner <michael.eu...@gmail.com> wrote:

> This bug came out of experimentation inspired by the recent discussion
> of initializing objects *after* their creation, a topic raised by
> Richard O'Keefe. And -- waddya know -- the problem here relates
> directly to his objection to this practice: inconsistent intermediate
> states. It appears that when you model your objects as processes, the
> danger is particularly acute.

If you had modeled the the set_arg_to and set_val_to as synchronous calls, like your function val_for – and like gen_server's call rather than cast – you can still do this. Though I still agree with ROK.

Cheers,

DBM

Erik Søe Sørensen

unread,
Apr 27, 2012, 4:18:28 PM4/27/12
to David Mercer, erlang-q...@erlang.org
Modeled as synchronous calls how exactly?
If taken literally, it sounds like you're suggesting that the process make synchronous calls to itself...

Michael Turner

unread,
Apr 28, 2012, 12:10:39 AM4/28/12
to Erik Søe Sørensen, erlang-q...@erlang.org
On Sat, Apr 28, 2012 at 5:18 AM, Erik Søe Sørensen <eri...@gmail.com> wrote:
> Modeled as synchronous calls how exactly?
> If taken literally, it sounds like you're suggesting that the process make
> synchronous calls to itself...

In this case, yes. Blind as I might be at times, I *can* see the more
trivial cases of deadlock.

Besides which, I'm looking for all the asynchrony I can get. The code
from which my simplified example was distilled is part of an attempt
to implement the natural language processing model outlined in
linguist Richard Hudson's Word Grammar,

http://www.phon.ucl.ac.uk/home/dick/WG/lntnwg.pdf

and it's not exactly clear where the human brain makes synchronous
calls to itself. Actually, a range of observable linguistic phenomena
suggest that nothing of the kind is involved. Formulating and uttering
a sentence might be something more like a team of people trying to
build a car, but sometimes dropping parts, picking the wrong part,
installing the right part the wrong way, bumping into each other
mid-task, dozing off on the job .... but mostly getting it right, most
of the time. In this sense, what I thought might be a bug was actually
just a misapplied feature.

-michael turner


> Den 27. apr. 2012 21.26 skrev David Mercer <dme...@gmail.com>:
>
>> On Apr 22, 2012, at 20:38, Michael Turner
>> <michael.eu...@gmail.com> wrote:
>>
>> > This bug came out of experimentation inspired by the recent discussion
>> > of initializing objects *after* their creation, a topic raised by
>> > Richard O'Keefe. And -- waddya know -- the problem here relates
>> > directly to his objection to this practice: inconsistent intermediate
>> > states. It appears that when you model your objects as processes, the
>> > danger is particularly acute.
>>
>> If you had modeled the the set_arg_to and set_val_to as synchronous calls,
>> like your function val_for – and like gen_server's call rather than cast –
>> you can still do this.  Though I still agree with ROK.
>>
>> Cheers,
>>
>> DBM
>
>
Reply all
Reply to author
Forward
0 new messages