Permalink
Browse files

make winner implicitly check a channel's done too

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 7e64b6ca7a4e1f35675a1b7e129b5c29f53ae834
Showing with 14 additions and 14 deletions.
  1. +14 −14 S17-concurrency.pod
View
@@ -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
@@ -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
@@ -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.
@@ -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 { ... }

0 comments on commit 7e64b6c

Please sign in to comment.