Skip to content

Commit

Permalink
Add "Redeemed" status and .redeem to Promise
Browse files Browse the repository at this point in the history
This would be the equivalent of Channel.close.
  • Loading branch information
lizmat committed Apr 5, 2014
1 parent 9e4c566 commit f136000
Showing 1 changed file with 22 additions and 16 deletions.
38 changes: 22 additions & 16 deletions S17-concurrency.pod
Expand Up @@ -256,16 +256,20 @@ Or C<break> it:
The current status of a C<Promise> is available through the C<status> method,
which returns an element from the C<PromiseStatus> enumeration.

enum PromiseStatus (:Planned(0), :Kept(1), :Broken(2));
enum PromiseStatus (:Planned(0), :Kept(1), :Broken(2), :Redeemed(3));

The result itself can be obtained by calling C<result>. If the C<Promise> was
already kept, the result is immediately returned. If the C<Promise> was broken
then the exception that it was broken with is thrown. If the C<Promise> is not
yet kept or broken, then the caller will block until this happens.
already kept, the result is immediately returned. If the C<Promise> was
broken then the exception that it was broken with is thrown.

A C<Promise> will boolify to whether the C<Promise> is already kept or broken.
There is also an C<excuse> method for extracting the exception from a C<Broken>
C<Promise> rather than having it thrown.
By redeeming a C<Promise>, you are basically marking it as "closed". So, if
a C<Promise> has been redeemed, then C<Nil> will be returned immediately.
If the C<Promise> is not yet kept, broken or redeemed, then the caller will
block until any of these status changes happen.

A C<Promise> will boolify to whether the C<Promise> is already kept, broken
or redeemed. There is also an C<excuse> method for extracting the exception
from a C<Broken> C<Promise> rather than having it thrown.

if $promise {
if $promise.status == Kept {
Expand All @@ -282,9 +286,10 @@ C<Promise> rather than having it thrown.
You can also simply use a switch:

given $promise.status {
when Planned { say "Still working!" }
when Kept { say "Kept, result = ", $promise.result }
when Broken { say "Broken because ", $promise.excuse }
when Planned { say "Still working!" }
when Kept { say "Kept, result = ", $promise.result }
when Broken { say "Broken because ", $promise.excuse }
when Redeemed { say "Water under the bridge" }
}

There are various convenient "factory" methods on C<Promise>. The most common
Expand Down Expand Up @@ -352,13 +357,14 @@ a promise is user-facing. To instead represent the promise from the
viewpoint of the promiser, the various built-in C<Promise> factory methods
and combinators use C<Promise::Vow> objects to represent that internal
resolve to fulfill the promise. ("I have vowed to keep my promise
to you.") The C<vow> method on a C<Promise> returns an object with C<keep>
and C<break> methods. It can only be called once during a C<Promise> object's
lifetime. Since C<keep> and C<break> on the C<Promise> itself just delegate
to C<self.vow.keep(...)> or C<self.vow.break(...)>, obtaining the vow
to you.") The C<vow> method on a C<Promise> returns an object with C<keep>,
C<break> and C<redeem> methods. It can only be called once during a
C<Promise> object's lifetime. Since C<keep>, C<break> and C<redeem> on the
C<Promise> itself just delegate to C<self.vow.keep(...)>,
C<self.vow.break(...)> or C<self.vow.redeem(...)>, obtaining the vow
before letting the C<Promise> escape to the outside world is a way to take
ownership of the right to keep or break it. For example, here is how the
C<Promise.in> factory is implemented:
ownership of the right to keep, break or redeem it. For example, here is how
the C<Promise.in> factory is implemented:

method in(Promise:U: $seconds, :$scheduler = $*SCHEDULER) {
my $p = Promise.new(:$scheduler);
Expand Down

0 comments on commit f136000

Please sign in to comment.