Skip to content

Supply blocks may reorder flow of execution #364

@patrickbkr

Description

@patrickbkr

This is a follow up of
rakudo/rakudo#5141
and
rakudo/rakudo#5158

Consider the following piece of code:

my $p = Promise.new;
my $s1 = supply {
    await $p;
    say "processing whenever"
};
react {
    whenever $s1 { }
    $p.keep;
    say "end of react block";
}

That piece of code prints

end of react block
processing whenever

This is unexpected. The order seems reversed. Why is this so?

By default whenevers tap their supply instantly and as a result run the supply block they are connected to. This has a potential for deadlocking when that supply block (or one nested via more whenevers) contains an emit as the emit will call the whenever block of the original supply, but by definition only a single execution branch is allowed in a supply block at any time.
Possibly (I'm not sure about that) there are other scenarios posing similar deadlock issues without recursion being involved.

The currently implemented solution for this deadlock problem in rakudo/rakudo@26a9c31 and rakudo/rakudo@5478392 works as follows. When - in the setup phase, during the processing of a whenever tapping - an await happens (be it a protect, acquire, lock or plain await) a continuation starting at the root of the whenever tapping is taken. Only after the supply block itself finished running the continuation is resumed. So the order in which the code is executed is dependent on whether there is any locking going on in code tapped by the whenever.

This behavior is difficult for a unknowing programmer to follow. Even a programmer knowing about this behavior will potentially have a hard time knowing whether there is a lock somewhere in the tapped code that could cause this reordering of code. This is a case of action-at-a-distance.

Also there still is a possibility of the code deadlocking left. That's detailed in rakudo/rakudo#5141. I consider that a problem separate from this issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    languageChanges to the Raku Programming Language

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions