Skip to content

Commit

Permalink
make winner implicitly check a channel's done too
Browse files Browse the repository at this point in the history
The concept of making a channel have a boolean operator to return the
done promise was bad for two reasons: 1) the logic of it was backwards
from promise booleans, and 2) making a boolean op return a non-boolean
is just a bad idea, and the person who proposed it should be ashamed.
  • Loading branch information
TimToady committed Nov 17, 2013
1 parent 71d18c5 commit 7e64b6c
Showing 1 changed file with 14 additions and 14 deletions.
28 changes: 14 additions & 14 deletions S17-concurrency.pod
Expand Up @@ -13,8 +13,8 @@ RE-DRAFT: Synopsis 17: Concurrency

Created: 3 Nov 2013

Last Modified: 15 Nov 2013
Version: 6
Last Modified: 16 Nov 2013
Version: 7

This synopsis is based around the concurrency primitives and tools currently
being implemented in Rakudo on the JVM. It covers both things that are
Expand Down Expand Up @@ -393,20 +393,22 @@ a result available.

The construct as a whole returns the result of whichever block was selected.

It's also possible to process a variadic list of promises together, using generic code
that works over some set of the promises (use C<*> to represent any of them). The index
and promise are passed to the code as named arguments C<$:v> and <$:k> (possible via priming if the
code is instantiated ahead of time).
It's also possible to process a variadic list of promises together,
using generic code that works over some set of the promises (use C<*>
to represent any of them). The index and promise are passed to the
code as named arguments C<$:v> and <$:k> (possibly via priming if
the code is instantiated ahead of time).

winner @promises {
done * { say "Promise $:k was kept, result was: ", $:v.result }
fail * { say "Promise $:k was broken }
}

In this case C<$:k> returns the index of the promise, base 0.
Likewise C<$:v> returns the promise object itself. Conjecture: the result
should be bound to C<$_> to make it work more like channels below.

[Conjecture: we should allow different cases for success or failure.]

=head2 Channels

A C<Channel> is essentially a concurrent queue. One or more threads can put
Expand Down Expand Up @@ -435,9 +437,8 @@ C<X::Channel::SendOnClosed> exception. Closing a channel has no effect on the
receiving end until all sent values have been received. At that point, any
further calls to receive will throw C<X::Channel::ReceiveOnClosed>. The
C<done> property returns a C<Promise> that is kept when the sender has
called C<done> and all sent messages have been received. For notational convenience,
C<< prefix:<!> >> returns the same promise. Note that multiple calls to a channel
return the same promise, not a new one.
called C<done> and all sent messages have been received. Note that multiple
calls to a channel return the same promise, not a new one.

While C<receive> blocks until it can read, C<poll> takes a message from the
channel if one is there or immediately returns C<Nil> if nothing is there.
Expand All @@ -446,18 +447,17 @@ of C<peek> is risky in any multi-receiver situation, since another worker may
receive the message you peeked.

The C<winner> construct also works on channels, and will try to receive a value
from the first C<Channel> that has one available. It can also be used in order
from the first C<Channel> that has one available. It also automatically checks
the .done promise corresponding to the channel, so it can also be used in order
to write a loop to receive from a channel until it is closed:

gather loop {
winner $c, !$c {
winner $c {
more * { take $_ }
done * { last }
}
}

[Conjecture, we can autogenerate !$c from $c.]

This is such a common pattern that we make a channel in list context behave that way:

for @$channel -> $val { ... }
Expand Down

0 comments on commit 7e64b6c

Please sign in to comment.