summaryrefslogtreecommitdiff
path: root/lib/Future.pm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Future.pm')
-rw-r--r--lib/Future.pm2200
1 files changed, 2200 insertions, 0 deletions
diff --git a/lib/Future.pm b/lib/Future.pm
new file mode 100644
index 0000000..07d7490
--- /dev/null
+++ b/lib/Future.pm
@@ -0,0 +1,2200 @@
+# You may distribute under the terms of either the GNU General Public License
+# or the Artistic License (the same terms as Perl itself)
+#
+# (C) Paul Evans, 2011-2015 -- leonerd@leonerd.org.uk
+
+package Future;
+
+use strict;
+use warnings;
+no warnings 'recursion'; # Disable the "deep recursion" warning
+
+our $VERSION = '0.32';
+
+use Carp qw(); # don't import croak
+use Scalar::Util qw( weaken blessed reftype );
+use B qw( svref_2object );
+use Time::HiRes qw( gettimeofday tv_interval );
+
+# we are not overloaded, but we want to check if other objects are
+require overload;
+
+our @CARP_NOT = qw( Future::Utils );
+
+use constant DEBUG => $ENV{PERL_FUTURE_DEBUG};
+
+our $TIMES = DEBUG || $ENV{PERL_FUTURE_TIMES};
+
+=head1 NAME
+
+C<Future> - represent an operation awaiting completion
+
+=head1 SYNOPSIS
+
+ my $future = Future->new;
+
+ perform_some_operation(
+ on_complete => sub {
+ $future->done( @_ );
+ }
+ );
+
+ $future->on_ready( sub {
+ say "The operation is complete";
+ } );
+
+=head1 DESCRIPTION
+
+A C<Future> object represents an operation that is currently in progress, or
+has recently completed. It can be used in a variety of ways to manage the flow
+of control, and data, through an asynchronous program.
+
+Some futures represent a single operation and are explicitly marked as ready
+by calling the C<done> or C<fail> methods. These are called "leaf" futures
+here, and are returned by the C<new> constructor.
+
+Other futures represent a collection of sub-tasks, and are implicitly marked
+as ready depending on the readiness of their component futures as required.
+These are called "convergent" futures here as they converge control and
+data-flow back into one place. These are the ones returned by the various
+C<wait_*> and C<need_*> constructors.
+
+It is intended that library functions that perform asynchronous operations
+would use future objects to represent outstanding operations, and allow their
+calling programs to control or wait for these operations to complete. The
+implementation and the user of such an interface would typically make use of
+different methods on the class. The methods below are documented in two
+sections; those of interest to each side of the interface.
+
+It should be noted however, that this module does not in any way provide an
+actual mechanism for performing this asynchronous activity; it merely provides
+a way to create objects that can be used for control and data flow around
+those operations. It allows such code to be written in a neater,
+forward-reading manner, and simplifies many common patterns that are often
+involved in such situations.
+
+See also L<Future::Utils> which contains useful loop-constructing functions,
+to run a future-returning function repeatedly in a loop.
+
+=head2 SUBCLASSING
+
+This class easily supports being subclassed to provide extra behavior, such as
+giving the C<get> method the ability to block and wait for completion. This
+may be useful to provide C<Future> subclasses with event systems, or similar.
+
+Each method that returns a new future object will use the invocant to
+construct its return value. If the constructor needs to perform per-instance
+setup it can override the C<new> method, and take context from the given
+instance.
+
+ sub new
+ {
+ my $proto = shift;
+ my $self = $proto->SUPER::new;
+
+ if( ref $proto ) {
+ # Prototype was an instance
+ }
+ else {
+ # Prototype was a class
+ }
+
+ return $self;
+ }
+
+If an instance provides a method called C<await>, this will be called by the
+C<get> and C<failure> methods if the instance is pending.
+
+ $f->await
+
+In most cases this should allow future-returning modules to be used as if they
+were blocking call/return-style modules, by simply appending a C<get> call to
+the function or method calls.
+
+ my ( $results, $here ) = future_returning_function( @args )->get;
+
+The F<examples> directory in the distribution contains some examples of how
+futures might be integrated with various event systems.
+
+=head2 MODULE DOCUMENTATION
+
+Modules that provide future-returning functions or methods may wish to adopt
+the following styles in some way, to document the eventual return values from
+these futures.
+
+ func( ARGS, HERE... ) ==> ( RETURN, VALUES... )
+
+ OBJ->method( ARGS, HERE... ) ==> ( RETURN, VALUES... )
+
+Code returning a future that yields no values on success can use empty
+parentheses.
+
+ func( ... ) ==> ()
+
+=head2 DEBUGGING
+
+By the time a C<Future> object is destroyed, it ought to have been completed
+or cancelled. By enabling debug tracing of objects, this fact can be checked.
+If a future object is destroyed without having been completed or cancelled, a
+warning message is printed.
+
+
+ $ PERL_FUTURE_DEBUG=1 perl -MFuture -E 'my $f = Future->new'
+ Future=HASH(0xaa61f8) was constructed at -e line 1 and was lost near -e line 0 before it was ready.
+
+Note that due to a limitation of perl's C<caller> function within a C<DESTROY>
+destructor method, the exact location of the leak cannot be accurately
+determined. Often the leak will occur due to falling out of scope by returning
+from a function; in this case the leak location may be reported as being the
+line following the line calling that function.
+
+ $ PERL_FUTURE_DEBUG=1 perl -MFuture
+ sub foo {
+ my $f = Future->new;
+ }
+
+ foo();
+ print "Finished\n";
+
+ Future=HASH(0x14a2220) was constructed at - line 2 and was lost near - line 6 before it was ready.
+ Finished
+
+A warning is also printed in debug mode if a C<Future> object is destroyed
+that completed with a failure, but the object believes that failure has not
+been reported anywhere.
+
+ $ PERL_FUTURE_DEBUG=1 perl -Mblib -MFuture -E 'my $f = Future->fail("Oops")'
+ Future=HASH(0xac98f8) was constructed at -e line 1 and was lost near -e line 0 with an unreported failure of: Oops
+
+Such a failure is considered reported if the C<get> or C<failure> methods are
+called on it, or it had at least one C<on_ready> or C<on_fail> callback, or
+its failure is propagated to another C<Future> instance (by a sequencing or
+converging method).
+
+=cut
+
+=head1 CONSTRUCTORS
+
+=cut
+
+=head2 $future = Future->new
+
+=head2 $future = $orig->new
+
+Returns a new C<Future> instance to represent a leaf future. It will be marked
+as ready by any of the C<done>, C<fail>, or C<cancel> methods. It can be
+called either as a class method, or as an instance method. Called on an
+instance it will construct another in the same class, and is useful for
+subclassing.
+
+This constructor would primarily be used by implementations of asynchronous
+interfaces.
+
+=cut
+
+# Callback flags
+use constant {
+ CB_DONE => 1<<0, # Execute callback on done
+ CB_FAIL => 1<<1, # Execute callback on fail
+ CB_CANCEL => 1<<2, # Execute callback on cancellation
+
+ CB_SELF => 1<<3, # Pass $self as first argument
+ CB_RESULT => 1<<4, # Pass result/failure as a list
+
+ CB_SEQ_ONDONE => 1<<5, # Sequencing on success (->then)
+ CB_SEQ_ONFAIL => 1<<6, # Sequencing on failure (->else)
+
+ CB_SEQ_IMDONE => 1<<7, # $code is in fact immediate ->done result
+ CB_SEQ_IMFAIL => 1<<8, # $code is in fact immediate ->fail result
+};
+
+use constant CB_ALWAYS => CB_DONE|CB_FAIL|CB_CANCEL;
+
+# Useful for identifying CODE references
+sub CvNAME_FILE_LINE
+{
+ my ( $code ) = @_;
+ my $cv = svref_2object( $code );
+
+ my $name = join "::", $cv->STASH->NAME, $cv->GV->NAME;
+ return $name unless $cv->GV->NAME eq "__ANON__";
+
+ # $cv->GV->LINE isn't reliable, as outside of perl -d mode all anon CODE
+ # in the same file actually shares the same GV. :(
+ # Walk the optree looking for the first COP
+ my $cop = $cv->START;
+ $cop = $cop->next while $cop and ref $cop ne "B::COP";
+
+ sprintf "%s(%s line %d)", $cv->GV->NAME, $cop->file, $cop->line;
+}
+
+sub _callable
+{
+ my ( $cb ) = @_;
+ defined $cb and ( reftype($cb) eq 'CODE' || overload::Method($cb, '&{}') );
+}
+
+sub new
+{
+ my $proto = shift;
+ return bless {
+ ready => 0,
+ callbacks => [], # [] = [$type, ...]
+ ( DEBUG ?
+ ( do { my $at = Carp::shortmess( "constructed" );
+ chomp $at; $at =~ s/\.$//;
+ constructed_at => $at } )
+ : () ),
+ ( $TIMES ?
+ ( btime => [ gettimeofday ] )
+ : () ),
+ }, ( ref $proto || $proto );
+}
+
+my $GLOBAL_END;
+END { $GLOBAL_END = 1; }
+
+sub DESTROY_debug {
+ my $self = shift;
+ return if $GLOBAL_END;
+ return if $self->{ready} and ( $self->{reported} or !$self->{failure} );
+
+ my $lost_at = join " line ", (caller)[1,2];
+ # We can't actually know the real line where the last reference was lost;
+ # a variable set to 'undef' or close of scope, because caller can't see it;
+ # the current op has already been updated. The best we can do is indicate
+ # 'near'.
+
+ if( $self->{ready} and $self->{failure} ) {
+ warn "${\$self->__selfstr} was $self->{constructed_at} and was lost near $lost_at with an unreported failure of: " .
+ $self->{failure}[0] . "\n";
+ }
+ elsif( !$self->{ready} ) {
+ warn "${\$self->__selfstr} was $self->{constructed_at} and was lost near $lost_at before it was ready.\n";
+ }
+}
+*DESTROY = \&DESTROY_debug if DEBUG;
+
+=head2 $future = Future->done( @values )
+
+=head2 $future = Future->fail( $exception, @details )
+
+Shortcut wrappers around creating a new C<Future> then immediately marking it
+as done or failed.
+
+=head2 $future = Future->wrap( @values )
+
+If given a single argument which is already a C<Future> reference, this will
+be returned unmodified. Otherwise, returns a new C<Future> instance that is
+already complete, and will yield the given values.
+
+This will ensure that an incoming argument is definitely a C<Future>, and may
+be useful in such cases as adapting synchronous code to fit asynchronous
+libraries driven by C<Future>.
+
+=cut
+
+sub wrap
+{
+ my $class = shift;
+ my @values = @_;
+
+ if( @values == 1 and blessed $values[0] and $values[0]->isa( __PACKAGE__ ) ) {
+ return $values[0];
+ }
+ else {
+ return $class->done( @values );
+ }
+}
+
+=head2 $future = Future->call( \&code, @args )
+
+A convenient wrapper for calling a C<CODE> reference that is expected to
+return a future. In normal circumstances is equivalent to
+
+ $future = $code->( @args )
+
+except that if the code throws an exception, it is wrapped in a new immediate
+fail future. If the return value from the code is not a blessed C<Future>
+reference, an immediate fail future is returned instead to complain about this
+fact.
+
+=cut
+
+sub call
+{
+ my $class = shift;
+ my ( $code, @args ) = @_;
+
+ my $f;
+ eval { $f = $code->( @args ); 1 } or $f = $class->fail( $@ );
+ blessed $f and $f->isa( "Future" ) or $f = $class->fail( "Expected " . CvNAME_FILE_LINE($code) . " to return a Future" );
+
+ return $f;
+}
+
+sub _shortmess
+{
+ my $at = Carp::shortmess( $_[0] );
+ chomp $at; $at =~ s/\.$//;
+ return $at;
+}
+
+sub _mark_ready
+{
+ my $self = shift;
+ $self->{ready} = 1;
+ $self->{ready_at} = _shortmess $_[0] if DEBUG;
+
+ if( $TIMES ) {
+ $self->{rtime} = [ gettimeofday ];
+ }
+
+ delete $self->{on_cancel};
+ my $callbacks = delete $self->{callbacks} or return;
+
+ my $cancelled = $self->{cancelled};
+ my $fail = defined $self->{failure};
+ my $done = !$fail && !$cancelled;
+
+ my @result = $done ? $self->get :
+ $fail ? $self->failure :
+ ();
+
+ foreach my $cb ( @$callbacks ) {
+ my ( $flags, $code ) = @$cb;
+ my $is_future = blessed( $code ) && $code->isa( "Future" );
+
+ next if $done and not( $flags & CB_DONE );
+ next if $fail and not( $flags & CB_FAIL );
+ next if $cancelled and not( $flags & CB_CANCEL );
+
+ $self->{reported} = 1 if $fail;
+
+ if( $is_future ) {
+ $done ? $code->done( @result ) :
+ $fail ? $code->fail( @result ) :
+ $code->cancel;
+ }
+ elsif( $flags & (CB_SEQ_ONDONE|CB_SEQ_ONFAIL) ) {
+ my ( undef, undef, $fseq ) = @$cb;
+ if( !$fseq ) { # weaken()ed; it might be gone now
+ # This warning should always be printed, even not in DEBUG mode.
+ # It's always an indication of a bug
+ Carp::carp +(DEBUG ? "${\$self->__selfstr} ($self->{constructed_at})"
+ : "${\$self->__selfstr} $self" ) .
+ " lost a sequence Future";
+ next;
+ }
+
+ my $f2;
+ if( $done and $flags & CB_SEQ_ONDONE or
+ $fail and $flags & CB_SEQ_ONFAIL ) {
+
+ if( $flags & CB_SEQ_IMDONE ) {
+ $fseq->done( @$code );
+ next;
+ }
+ elsif( $flags & CB_SEQ_IMFAIL ) {
+ $fseq->fail( @$code );
+ next;
+ }
+
+ my @args = (
+ ( $flags & CB_SELF ? $self : () ),
+ ( $flags & CB_RESULT ? @result : () ),
+ );
+
+ unless( eval { $f2 = $code->( @args ); 1 } ) {
+ $fseq->fail( $@ );
+ next;
+ }
+
+ unless( blessed $f2 and $f2->isa( "Future" ) ) {
+ $fseq->fail( "Expected " . CvNAME_FILE_LINE($code) . " to return a Future" );
+ next;
+ }
+
+ $fseq->on_cancel( $f2 );
+ }
+ else {
+ $f2 = $self;
+ }
+
+ if( $f2->is_ready ) {
+ $f2->on_ready( $fseq ) if !$f2->{cancelled};
+ }
+ else {
+ push @{ $f2->{callbacks} }, [ CB_DONE|CB_FAIL, $fseq ];
+ weaken( $f2->{callbacks}[-1][1] );
+ }
+ }
+ else {
+ $code->(
+ ( $flags & CB_SELF ? $self : () ),
+ ( $flags & CB_RESULT ? @result : () ),
+ );
+ }
+ }
+}
+
+sub _state
+{
+ my $self = shift;
+ return !$self->{ready} ? "pending" :
+ DEBUG ? $self->{ready_at} :
+ $self->{failure} ? "failed" :
+ $self->{cancelled} ? "cancelled" :
+ "done";
+}
+
+=head1 IMPLEMENTATION METHODS
+
+These methods would primarily be used by implementations of asynchronous
+interfaces.
+
+=cut
+
+=head2 $future->done( @result )
+
+Marks that the leaf future is now ready, and provides a list of values as a
+result. (The empty list is allowed, and still indicates the future as ready).
+Cannot be called on a convergent future.
+
+If the future is already cancelled, this request is ignored. If the future is
+already complete with a result or a failure, an exception is thrown.
+
+=head2 Future->done( @result )
+
+May also be called as a class method, where it will construct a new Future and
+immediately mark it as done.
+
+Returns the C<$future> to allow easy chaining to create an immediate future by
+
+ return Future->done( ... )
+
+=cut
+
+sub done
+{
+ my $self = shift;
+
+ if( ref $self ) {
+ $self->{cancelled} and return $self;
+ $self->{ready} and Carp::croak "${\$self->__selfstr} is already ".$self->_state." and cannot be ->done";
+ $self->{subs} and Carp::croak "${\$self->__selfstr} is not a leaf Future, cannot be ->done";
+ $self->{result} = [ @_ ];
+ $self->_mark_ready( "done" );
+ }
+ else {
+ $self = $self->new;
+ $self->{ready} = 1;
+ $self->{ready_at} = _shortmess "done" if DEBUG;
+ $self->{result} = [ @_ ];
+ }
+
+ return $self;
+}
+
+=head2 $code = $future->done_cb
+
+Returns a C<CODE> reference that, when invoked, calls the C<done> method. This
+makes it simple to pass as a callback function to other code.
+
+As the same effect can be achieved using L<curry>, this method is deprecated
+now and may be removed in a later version.
+
+ $code = $future->curry::done;
+
+=cut
+
+sub done_cb
+{
+ my $self = shift;
+ return sub { $self->done( @_ ) };
+}
+
+=head2 $future->fail( $exception, @details )
+
+Marks that the leaf future has failed, and provides an exception value. This
+exception will be thrown by the C<get> method if called.
+
+The exception must evaluate as a true value; false exceptions are not allowed.
+Further details may be provided that will be returned by the C<failure> method
+in list context. These details will not be part of the exception string raised
+by C<get>.
+
+If the future is already cancelled, this request is ignored. If the future is
+already complete with a result or a failure, an exception is thrown.
+
+=head2 Future->fail( $exception, @details )
+
+May also be called as a class method, where it will construct a new Future and
+immediately mark it as failed.
+
+Returns the C<$future> to allow easy chaining to create an immediate failed
+future by
+
+ return Future->fail( ... )
+
+=cut
+
+sub fail
+{
+ my $self = shift;
+ my ( $exception, @details ) = @_;
+
+ $_[0] or Carp::croak "$self ->fail requires an exception that is true";
+
+ if( ref $self ) {
+ $self->{cancelled} and return $self;
+ $self->{ready} and Carp::croak "${\$self->__selfstr} is already ".$self->_state." and cannot be ->fail'ed";
+ $self->{subs} and Carp::croak "${\$self->__selfstr} is not a leaf Future, cannot be ->fail'ed";
+ $self->{failure} = [ $exception, @details ];
+ $self->_mark_ready( "fail" );
+ }
+ else {
+ $self = $self->new;
+ $self->{ready} = 1;
+ $self->{ready_at} = _shortmess "fail" if DEBUG;
+ $self->{failure} = [ $exception, @details ];
+ }
+
+ if( DEBUG ) {
+ my $at = Carp::shortmess( "failed" );
+ chomp $at; $at =~ s/\.$//;
+ $self->{ready_at} = $at;
+ }
+
+ return $self;
+}
+
+=head2 $code = $future->fail_cb
+
+Returns a C<CODE> reference that, when invoked, calls the C<fail> method. This
+makes it simple to pass as a callback function to other code.
+
+As the same effect can be achieved using L<curry>, this method is deprecated
+now and may be removed in a later version.
+
+ $code = $future->curry::fail;
+
+=cut
+
+sub fail_cb
+{
+ my $self = shift;
+ return sub { $self->fail( @_ ) };
+}
+
+=head2 $future->die( $message, @details )
+
+A convenient wrapper around C<fail>. If the exception is a non-reference that
+does not end in a linefeed, its value will be extended by the file and line
+number of the caller, similar to the logic that C<die> uses.
+
+Returns the C<$future>.
+
+=cut
+
+sub die :method
+{
+ my $self = shift;
+ my ( $exception, @details ) = @_;
+
+ if( !ref $exception and $exception !~ m/\n$/ ) {
+ $exception .= sprintf " at %s line %d\n", (caller)[1,2];
+ }
+
+ $self->fail( $exception, @details );
+}
+
+=head2 $future->on_cancel( $code )
+
+If the future is not yet ready, adds a callback to be invoked if the future is
+cancelled by the C<cancel> method. If the future is already ready, throws an
+exception.
+
+If the future is cancelled, the callbacks will be invoked in the reverse order
+to that in which they were registered.
+
+ $on_cancel->( $future )
+
+=head2 $future->on_cancel( $f )
+
+If passed another C<Future> instance, the passed instance will be cancelled
+when the original future is cancelled. This method does nothing if the future
+is already complete.
+
+=cut
+
+sub on_cancel
+{
+ my $self = shift;
+ my ( $code ) = @_;
+
+ my $is_future = blessed( $code ) && $code->isa( "Future" );
+ $is_future or _callable( $code ) or
+ Carp::croak "Expected \$code to be callable or a Future in ->on_cancel";
+
+ $self->{ready} and return $self;
+
+ push @{ $self->{on_cancel} }, $code;
+
+ return $self;
+}
+
+=head2 $cancelled = $future->is_cancelled
+
+Returns true if the future has been cancelled by C<cancel>.
+
+=cut
+
+sub is_cancelled
+{
+ my $self = shift;
+ return $self->{cancelled};
+}
+
+=head1 USER METHODS
+
+These methods would primarily be used by users of asynchronous interfaces, on
+objects returned by such an interface.
+
+=cut
+
+=head2 $ready = $future->is_ready
+
+Returns true on a leaf future if a result has been provided to the C<done>
+method, failed using the C<fail> method, or cancelled using the C<cancel>
+method.
+
+Returns true on a convergent future if it is ready to yield a result,
+depending on its component futures.
+
+=cut
+
+sub is_ready
+{
+ my $self = shift;
+ return $self->{ready};
+}
+
+=head2 $future->on_ready( $code )
+
+If the future is not yet ready, adds a callback to be invoked when the future
+is ready. If the future is already ready, invokes it immediately.
+
+In either case, the callback will be passed the future object itself. The
+invoked code can then obtain the list of results by calling the C<get> method.
+
+ $on_ready->( $future )
+
+Returns the C<$future>.
+
+=head2 $future->on_ready( $f )
+
+If passed another C<Future> instance, the passed instance will have its
+C<done>, C<fail> or C<cancel> methods invoked when the original future
+completes successfully, fails, or is cancelled respectively.
+
+=cut
+
+sub on_ready
+{
+ my $self = shift;
+ my ( $code ) = @_;
+
+ my $is_future = blessed( $code ) && $code->isa( "Future" );
+ $is_future or _callable( $code ) or
+ Carp::croak "Expected \$code to be callable or a Future in ->on_ready";
+
+ if( $self->{ready} ) {
+ my $fail = defined $self->{failure};
+ my $done = !$fail && !$self->{cancelled};
+
+ $self->{reported} = 1 if $fail;
+
+ $is_future ? ( $done ? $code->done( $self->get ) :
+ $fail ? $code->fail( $self->failure ) :
+ $code->cancel )
+ : $code->( $self );
+ }
+ else {
+ push @{ $self->{callbacks} }, [ CB_ALWAYS|CB_SELF, $self->wrap_cb( on_ready => $code ) ];
+ }
+
+ return $self;
+}
+
+=head2 $done = $future->is_done
+
+Returns true on a future if it is ready and completed successfully. Returns
+false if it is still pending, failed, or was cancelled.
+
+=cut
+
+sub is_done
+{
+ my $self = shift;
+ return $self->{ready} && !$self->{failure} && !$self->{cancelled};
+}
+
+=head2 @result = $future->get
+
+=head2 $result = $future->get
+
+If the future is ready and completed successfully, returns the list of
+results that had earlier been given to the C<done> method on a leaf future,
+or the list of component futures it was waiting for on a convergent future. In
+scalar context it returns just the first result value.
+
+If the future is ready but failed, this method raises as an exception the
+failure string or object that was given to the C<fail> method.
+
+If the future was cancelled an exception is thrown.
+
+If it is not yet ready and is not of a subclass that provides an C<await>
+method an exception is thrown. If it is subclassed to provide an C<await>
+method then this is used to wait for the future to be ready, before returning
+the result or propagating its failure exception.
+
+=cut
+
+sub await
+{
+ my $self = shift;
+ Carp::croak "$self is not yet complete and does not provide ->await";
+}
+
+sub get
+{
+ my $self = shift;
+ $self->await until $self->{ready};
+ if( $self->{failure} ) {
+ $self->{reported} = 1;
+ my $exception = $self->{failure}->[0];
+ !ref $exception && $exception =~ m/\n$/ ? CORE::die $exception : Carp::croak $exception;
+ }
+ $self->{cancelled} and Carp::croak "${\$self->__selfstr} was cancelled";
+ return $self->{result}->[0] unless wantarray;
+ return @{ $self->{result} };
+}
+
+=head2 @values = Future->unwrap( @values )
+
+If given a single argument which is a C<Future> reference, this method will
+call C<get> on it and return the result. Otherwise, it returns the list of
+values directly in list context, or the first value in scalar. Since it
+involves an implicit C<await>, this method can only be used on immediate
+futures or subclasses that implement C<await>.
+
+This will ensure that an outgoing argument is definitely not a C<Future>, and
+may be useful in such cases as adapting synchronous code to fit asynchronous
+libraries that return C<Future> instances.
+
+=cut
+
+sub unwrap
+{
+ shift; # $class
+ my @values = @_;
+
+ if( @values == 1 and blessed $values[0] and $values[0]->isa( __PACKAGE__ ) ) {
+ return $values[0]->get;
+ }
+ else {
+ return $values[0] if !wantarray;
+ return @values;
+ }
+}
+
+=head2 $future->on_done( $code )
+
+If the future is not yet ready, adds a callback to be invoked when the future
+is ready, if it completes successfully. If the future completed successfully,
+invokes it immediately. If it failed or was cancelled, it is not invoked at
+all.
+
+The callback will be passed the result passed to the C<done> method.
+
+ $on_done->( @result )
+
+Returns the C<$future>.
+
+=head2 $future->on_done( $f )
+
+If passed another C<Future> instance, the passed instance will have its
+C<done> method invoked when the original future completes successfully.
+
+=cut
+
+sub on_done
+{
+ my $self = shift;
+ my ( $code ) = @_;
+
+ my $is_future = blessed( $code ) && $code->isa( "Future" );
+ $is_future or _callable( $code ) or
+ Carp::croak "Expected \$code to be callable or a Future in ->on_done";
+
+ if( $self->{ready} ) {
+ return $self if $self->{failure} or $self->{cancelled};
+
+ $is_future ? $code->done( $self->get )
+ : $code->( $self->get );
+ }
+ else {
+ push @{ $self->{callbacks} }, [ CB_DONE|CB_RESULT, $self->wrap_cb( on_done => $code ) ];
+ }
+
+ return $self;
+}
+
+=head2 $failed = $future->is_failed
+
+Returns true on a future if it is ready and it failed. Returns false if it is
+still pending, completed successfully, or was cancelled.
+
+=cut
+
+sub is_failed
+{
+ my $self = shift;
+ return $self->{ready} && !!$self->{failure}; # boolify
+}
+
+=head2 $exception = $future->failure
+
+=head2 $exception, @details = $future->failure
+
+Returns the exception passed to the C<fail> method, C<undef> if the future
+completed successfully via the C<done> method, or raises an exception if
+called on a future that is not yet ready.
+
+If called in list context, will additionally yield a list of the details
+provided to the C<fail> method.
+
+Because the exception value must be true, this can be used in a simple C<if>
+statement:
+
+ if( my $exception = $future->failure ) {
+ ...
+ }
+ else {
+ my @result = $future->get;
+ ...
+ }
+
+=cut
+
+sub failure
+{
+ my $self = shift;
+ $self->await until $self->{ready};
+ return unless $self->{failure};
+ $self->{reported} = 1;
+ return $self->{failure}->[0] if !wantarray;
+ return @{ $self->{failure} };
+}
+
+=head2 $future->on_fail( $code )
+
+If the future is not yet ready, adds a callback to be invoked when the future
+is ready, if it fails. If the future has already failed, invokes it
+immediately. If it completed successfully or was cancelled, it is not invoked
+at all.
+
+The callback will be passed the exception and details passed to the C<fail>
+method.
+
+ $on_fail->( $exception, @details )
+
+Returns the C<$future>.
+
+=head2 $future->on_fail( $f )
+
+If passed another C<Future> instance, the passed instance will have its
+C<fail> method invoked when the original future fails.
+
+To invoke a C<done> method on a future when another one fails, use a CODE
+reference:
+
+ $future->on_fail( sub { $f->done( @_ ) } );
+
+=cut
+
+sub on_fail
+{
+ my $self = shift;
+ my ( $code ) = @_;
+
+ my $is_future = blessed( $code ) && $code->isa( "Future" );
+ $is_future or _callable( $code ) or
+ Carp::croak "Expected \$code to be callable or a Future in ->on_fail";
+
+ if( $self->{ready} ) {
+ return $self if not $self->{failure};
+ $self->{reported} = 1;
+
+ $is_future ? $code->fail( $self->failure )
+ : $code->( $self->failure );
+ }
+ else {
+ push @{ $self->{callbacks} }, [ CB_FAIL|CB_RESULT, $self->wrap_cb( on_fail => $code ) ];
+ }
+
+ return $self;
+}
+
+=head2 $future->cancel
+
+Requests that the future be cancelled, immediately marking it as ready. This
+will invoke all of the code blocks registered by C<on_cancel>, in the reverse
+order. When called on a convergent future, all its component futures are also
+cancelled. It is not an error to attempt to cancel a future that is already
+complete or cancelled; it simply has no effect.
+
+Returns the C<$future>.
+
+=cut
+
+sub cancel
+{
+ my $self = shift;
+
+ return $self if $self->{ready};
+
+ $self->{cancelled}++;
+ foreach my $code ( reverse @{ $self->{on_cancel} || [] } ) {
+ my $is_future = blessed( $code ) && $code->isa( "Future" );
+ $is_future ? $code->cancel
+ : $code->( $self );
+ }
+ $self->_mark_ready( "cancel" );
+
+ return $self;
+}
+
+=head2 $code = $future->cancel_cb
+
+Returns a C<CODE> reference that, when invoked, calls the C<cancel> method.
+This makes it simple to pass as a callback function to other code.
+
+As the same effect can be achieved using L<curry>, this method is deprecated
+now and may be removed in a later version.
+
+ $code = $future->curry::cancel;
+
+=cut
+
+sub cancel_cb
+{
+ my $self = shift;
+ return sub { $self->cancel };
+}
+
+=head1 SEQUENCING METHODS
+
+The following methods all return a new future to represent the combination of
+its invocant followed by another action given by a code reference. The
+combined activity waits for the first future to be ready, then may invoke the
+code depending on the success or failure of the first, or may run it
+regardless. The returned sequence future represents the entire combination of
+activity.
+
+In some cases the code should return a future; in some it should return an
+immediate result. If a future is returned, the combined future will then wait
+for the result of this second one. If the combinined future is cancelled, it
+will cancel either the first future or the second, depending whether the first
+had completed. If the code block throws an exception instead of returning a
+value, the sequence future will fail with that exception as its message and no
+further values.
+
+As it is always a mistake to call these sequencing methods in void context and lose the
+reference to the returned future (because exception/error handling would be
+silently dropped), this method warns in void context.
+
+=cut
+
+sub _sequence
+{
+ my $f1 = shift;
+ my ( $code, $flags ) = @_;
+
+ # For later, we might want to know where we were called from
+ my $func = (caller 1)[3];
+ $func =~ s/^.*:://;
+
+ $flags & (CB_SEQ_IMDONE|CB_SEQ_IMFAIL) or _callable( $code ) or
+ Carp::croak "Expected \$code to be callable in ->$func";
+
+ if( !defined wantarray ) {
+ Carp::carp "Calling ->$func in void context";
+ }
+
+ if( $f1->is_ready ) {
+ # Take a shortcut
+ return $f1 if $f1->is_done and not( $flags & CB_SEQ_ONDONE ) or
+ $f1->failure and not( $flags & CB_SEQ_ONFAIL );
+
+ if( $flags & CB_SEQ_IMDONE ) {
+ return Future->done( @$code );
+ }
+ elsif( $flags & CB_SEQ_IMFAIL ) {
+ return Future->fail( @$code );
+ }
+
+ my @args = (
+ ( $flags & CB_SELF ? $f1 : () ),
+ ( $flags & CB_RESULT ? $f1->is_done ? $f1->get :
+ $f1->failure ? $f1->failure :
+ () : () ),
+ );
+
+ my $fseq;
+ unless( eval { $fseq = $code->( @args ); 1 } ) {
+ return Future->fail( $@ );
+ }
+
+ unless( blessed $fseq and $fseq->isa( "Future" ) ) {
+ return Future->fail( "Expected " . CvNAME_FILE_LINE($code) . " to return a Future" );
+ }
+
+ return $fseq;
+ }
+
+ my $fseq = $f1->new;
+ $fseq->on_cancel( $f1 );
+
+ # TODO: if anyone cares about the op name, we might have to synthesize it
+ # from $flags
+ $code = $f1->wrap_cb( sequence => $code ) unless $flags & (CB_SEQ_IMDONE|CB_SEQ_IMFAIL);
+
+ push @{ $f1->{callbacks} }, [ CB_DONE|CB_FAIL|$flags, $code, $fseq ];
+ weaken( $f1->{callbacks}[-1][2] );
+
+ return $fseq;
+}
+
+=head2 $future = $f1->then( \&done_code )
+
+Returns a new sequencing C<Future> that runs the code if the first succeeds.
+Once C<$f1> succeeds the code reference will be invoked and is passed the list
+of results. It should return a future, C<$f2>. Once C<$f2> completes the
+sequence future will then be marked as complete with whatever result C<$f2>
+gave. If C<$f1> fails then the sequence future will immediately fail with the
+same failure and the code will not be invoked.
+
+ $f2 = $done_code->( @result )
+
+=head2 $future = $f1->else( \&fail_code )
+
+Returns a new sequencing C<Future> that runs the code if the first fails. Once
+C<$f1> fails the code reference will be invoked and is passed the failure and
+details. It should return a future, C<$f2>. Once C<$f2> completes the sequence
+future will then be marked as complete with whatever result C<$f2> gave. If
+C<$f1> succeeds then the sequence future will immediately succeed with the
+same result and the code will not be invoked.
+
+ $f2 = $fail_code->( $exception, @details )
+
+=head2 $future = $f1->then( \&done_code, \&fail_code )
+
+The C<then> method can also be passed the C<$fail_code> block as well, giving
+a combination of C<then> and C<else> behaviour.
+
+This operation is designed to be compatible with the semantics of other future
+systems, such as Javascript's Q or Promises/A libraries.
+
+=cut
+
+sub then
+{
+ my $self = shift;
+ my ( $done_code, $fail_code ) = @_;
+
+ if( $done_code and !$fail_code ) {
+ return $self->_sequence( $done_code, CB_SEQ_ONDONE|CB_RESULT );
+ }
+
+ !$done_code or _callable( $done_code ) or
+ Carp::croak "Expected \$done_code to be callable in ->then";
+ !$fail_code or _callable( $fail_code ) or
+ Carp::croak "Expected \$fail_code to be callable in ->then";
+
+ # Complex
+ return $self->_sequence( sub {
+ my $self = shift;
+ if( !$self->{failure} ) {
+ return $self unless $done_code;
+ return $done_code->( $self->get );
+ }
+ else {
+ return $self unless $fail_code;
+ return $fail_code->( $self->failure );
+ }
+ }, CB_SEQ_ONDONE|CB_SEQ_ONFAIL|CB_SELF );
+}
+
+sub else
+{
+ my $self = shift;
+ my ( $fail_code ) = @_;
+
+ return $self->_sequence( $fail_code, CB_SEQ_ONFAIL|CB_RESULT );
+}
+
+=head2 $future = $f1->transform( %args )
+
+Returns a new sequencing C<Future> that wraps the one given as C<$f1>. With no
+arguments this will be a trivial wrapper; C<$future> will complete or fail
+when C<$f1> does, and C<$f1> will be cancelled when C<$future> is.
+
+By passing the following named arguments, the returned C<$future> can be made
+to behave differently to C<$f1>:
+
+=over 8
+
+=item done => CODE
+
+Provides a function to use to modify the result of a successful completion.
+When C<$f1> completes successfully, the result of its C<get> method is passed
+into this function, and whatever it returns is passed to the C<done> method of
+C<$future>
+
+=item fail => CODE
+
+Provides a function to use to modify the result of a failure. When C<$f1>
+fails, the result of its C<failure> method is passed into this function, and
+whatever it returns is passed to the C<fail> method of C<$future>.
+
+=back
+
+=cut
+
+sub transform
+{
+ my $self = shift;
+ my %args = @_;
+
+ my $xfrm_done = $args{done};
+ my $xfrm_fail = $args{fail};
+
+ return $self->_sequence( sub {
+ my $self = shift;
+ if( !$self->{failure} ) {
+ return $self unless $xfrm_done;
+ my @result = $xfrm_done->( $self->get );
+ return $self->new->done( @result );
+ }
+ else {
+ return $self unless $xfrm_fail;
+ my @failure = $xfrm_fail->( $self->failure );
+ return $self->new->fail( @failure );
+ }
+ }, CB_SEQ_ONDONE|CB_SEQ_ONFAIL|CB_SELF );
+}
+
+=head2 $future = $f1->then_with_f( \&code )
+
+Returns a new sequencing C<Future> that runs the code if the first succeeds.
+Identical to C<then>, except that the code reference will be passed both the
+original future, C<$f1>, and its result.
+
+ $f2 = $code->( $f1, @result )
+
+This is useful for conditional execution cases where the code block may just
+return the same result of the original future. In this case it is more
+efficient to return the original future itself.
+
+=cut
+
+sub then_with_f
+{
+ my $self = shift;
+ my ( $done_code ) = @_;
+
+ return $self->_sequence( $done_code, CB_SEQ_ONDONE|CB_SELF|CB_RESULT );
+}
+
+=head2 $future = $f->then_done( @result )
+
+=head2 $future = $f->then_fail( $exception, @details )
+
+Convenient shortcuts to returning an immediate future from a C<then> block,
+when the result is already known.
+
+=cut
+
+sub then_done
+{
+ my $self = shift;
+ my ( @result ) = @_;
+ return $self->_sequence( \@result, CB_SEQ_ONDONE|CB_SEQ_IMDONE );
+}
+
+sub then_fail
+{
+ my $self = shift;
+ my ( @failure ) = @_;
+ return $self->_sequence( \@failure, CB_SEQ_ONDONE|CB_SEQ_IMFAIL );
+}
+
+=head2 $future = $f1->else_with_f( \&code )
+
+Returns a new sequencing C<Future> that runs the code if the first fails.
+Identical to C<else>, except that the code reference will be passed both the
+original future, C<$f1>, and its exception and details.
+
+ $f2 = $code->( $f1, $exception, @details )
+
+This is useful for conditional execution cases where the code block may just
+return the same result of the original future. In this case it is more
+efficient to return the original future itself.
+
+=cut
+
+sub else_with_f
+{
+ my $self = shift;
+ my ( $fail_code ) = @_;
+
+ return $self->_sequence( $fail_code, CB_SEQ_ONFAIL|CB_SELF|CB_RESULT );
+}
+
+=head2 $future = $f->else_done( @result )
+
+=head2 $future = $f->else_fail( $exception, @details )
+
+Convenient shortcuts to returning an immediate future from a C<else> block,
+when the result is already known.
+
+=cut
+
+sub else_done
+{
+ my $self = shift;
+ my ( @result ) = @_;
+ return $self->_sequence( \@result, CB_SEQ_ONFAIL|CB_SEQ_IMDONE );
+}
+
+sub else_fail
+{
+ my $self = shift;
+ my ( @failure ) = @_;
+ return $self->_sequence( \@failure, CB_SEQ_ONFAIL|CB_SEQ_IMFAIL );
+}
+
+=head2 $future = $f1->followed_by( \&code )
+
+Returns a new sequencing C<Future> that runs the code regardless of success or
+failure. Once C<$f1> is ready the code reference will be invoked and is passed
+one argument, C<$f1>. It should return a future, C<$f2>. Once C<$f2> completes
+the sequence future will then be marked as complete with whatever result
+C<$f2> gave.
+
+ $f2 = $code->( $f1 )
+
+=cut
+
+sub followed_by
+{
+ my $self = shift;
+ my ( $code ) = @_;
+
+ return $self->_sequence( $code, CB_SEQ_ONDONE|CB_SEQ_ONFAIL|CB_SELF );
+}
+
+sub and_then
+{
+ Carp::croak "Future->and_then is now removed; use ->then_with_f instead";
+}
+
+sub or_else
+{
+ Carp::croak "Future->or_else is now removed; use ->else_with_f instead";
+}
+
+=head2 $future = $f1->without_cancel
+
+Returns a new sequencing C<Future> that will complete with the success or
+failure of the original future, but if cancelled, will not cancel the
+original. This may be useful if the original future represents an operation
+that is being shared among multiple sequences; cancelling one should not
+prevent the others from running too.
+
+=cut
+
+sub without_cancel
+{
+ my $self = shift;
+ my $new = $self->new;
+
+ $self->on_ready( sub {
+ my $self = shift;
+ if( $self->failure ) {
+ $new->fail( $self->failure );
+ }
+ else {
+ $new->done( $self->get );
+ }
+ });
+
+ return $new;
+}
+
+=head1 CONVERGENT FUTURES
+
+The following constructors all take a list of component futures, and return a
+new future whose readiness somehow depends on the readiness of those
+components. The first derived class component future will be used as the
+prototype for constructing the return value, so it respects subclassing
+correctly, or failing that a plain C<Future>.
+
+=cut
+
+sub _new_convergent
+{
+ shift; # ignore this class
+ my ( $subs ) = @_;
+
+ foreach my $sub ( @$subs ) {
+ blessed $sub and $sub->isa( "Future" ) or Carp::croak "Expected a Future, got $_";
+ }
+
+ # Find the best prototype. Ideally anything derived if we can find one.
+ my $self;
+ ref($_) eq "Future" or $self = $_->new, last for @$subs;
+
+ # No derived ones; just have to be a basic class then
+ $self ||= Future->new;
+
+ $self->{subs} = $subs;
+
+ # This might be called by a DESTROY during global destruction so it should
+ # be as defensive as possible (see RT88967)
+ $self->on_cancel( sub {
+ foreach my $sub ( @$subs ) {
+ $sub->cancel if $sub and !$sub->{ready};
+ }
+ } );
+
+ return $self;
+}
+
+=head2 $future = Future->wait_all( @subfutures )
+
+Returns a new C<Future> instance that will indicate it is ready once all of
+the sub future objects given to it indicate that they are ready, either by
+success, failure or cancellation. Its result will a list of its component
+futures.
+
+When given an empty list this constructor returns a new immediately-done
+future.
+
+This constructor would primarily be used by users of asynchronous interfaces.
+
+=cut
+
+sub wait_all
+{
+ my $class = shift;
+ my @subs = @_;
+
+ unless( @subs ) {
+ my $self = $class->done;
+ $self->{subs} = [];
+ return $self;
+ }
+
+ my $self = Future->_new_convergent( \@subs );
+
+ my $pending = 0;
+ $_->{ready} or $pending++ for @subs;
+
+ # Look for immediate ready
+ if( !$pending ) {
+ $self->{result} = [ @subs ];
+ $self->_mark_ready( "wait_all" );
+ return $self;
+ }
+
+ weaken( my $weakself = $self );
+ my $sub_on_ready = sub {
+ return unless $weakself;
+
+ $pending--;
+ $pending and return;
+
+ $weakself->{result} = [ @subs ];
+ $weakself->_mark_ready( "wait_all" );
+ };
+
+ foreach my $sub ( @subs ) {
+ $sub->{ready} or $sub->on_ready( $sub_on_ready );
+ }
+
+ return $self;
+}
+
+=head2 $future = Future->wait_any( @subfutures )
+
+Returns a new C<Future> instance that will indicate it is ready once any of
+the sub future objects given to it indicate that they are ready, either by
+success or failure. Any remaining component futures that are not yet ready
+will be cancelled. Its result will be the result of the first component future
+that was ready; either success or failure. Any component futures that are
+cancelled are ignored, apart from the final component left; at which point the
+result will be a failure.
+
+When given an empty list this constructor returns an immediately-failed
+future.
+
+This constructor would primarily be used by users of asynchronous interfaces.
+
+=cut
+
+sub wait_any
+{
+ my $class = shift;
+ my @subs = @_;
+
+ unless( @subs ) {
+ my $self = $class->fail( "Cannot ->wait_any with no subfutures" );
+ $self->{subs} = [];
+ return $self;
+ }
+
+ my $self = Future->_new_convergent( \@subs );
+
+ # Look for immediate ready
+ my $immediate_ready;
+ foreach my $sub ( @subs ) {
+ $sub->{ready} and $immediate_ready = $sub, last;
+ }
+
+ if( $immediate_ready ) {
+ foreach my $sub ( @subs ) {
+ $sub->{ready} or $sub->cancel;
+ }
+
+ if( $immediate_ready->{failure} ) {
+ $self->{failure} = [ $immediate_ready->failure ];
+ }
+ else {
+ $self->{result} = [ $immediate_ready->get ];
+ }
+ $self->_mark_ready( "wait_any" );
+ return $self;
+ }
+
+ my $pending = 0;
+
+ weaken( my $weakself = $self );
+ my $sub_on_ready = sub {
+ return unless $weakself;
+ return if $weakself->{result} or $weakself->{failure}; # don't recurse on child ->cancel
+
+ return if --$pending and $_[0]->{cancelled};
+
+ if( $_[0]->{cancelled} ) {
+ $weakself->{failure} = [ "All component futures were cancelled" ];
+ }
+ elsif( $_[0]->{failure} ) {
+ $weakself->{failure} = [ $_[0]->failure ];
+ }
+ else {
+ $weakself->{result} = [ $_[0]->get ];
+ }
+
+ foreach my $sub ( @subs ) {
+ $sub->{ready} or $sub->cancel;
+ }
+
+ $weakself->_mark_ready( "wait_any" );
+ };
+
+ foreach my $sub ( @subs ) {
+ # No need to test $sub->{ready} since we know none of them are
+ $sub->on_ready( $sub_on_ready );
+ $pending++;
+ }
+
+ return $self;
+}
+
+=head2 $future = Future->needs_all( @subfutures )
+
+Returns a new C<Future> instance that will indicate it is ready once all of the
+sub future objects given to it indicate that they have completed successfully,
+or when any of them indicates that they have failed. If any sub future fails,
+then this will fail immediately, and the remaining subs not yet ready will be
+cancelled. Any component futures that are cancelled will cause an immediate
+failure of the result.
+
+If successful, its result will be a concatenated list of the results of all
+its component futures, in corresponding order. If it fails, its failure will
+be that of the first component future that failed. To access each component
+future's results individually, use C<done_futures>.
+
+When given an empty list this constructor returns a new immediately-done
+future.
+
+This constructor would primarily be used by users of asynchronous interfaces.
+
+=cut
+
+sub needs_all
+{
+ my $class = shift;
+ my @subs = @_;
+
+ unless( @subs ) {
+ my $self = $class->done;
+ $self->{subs} = [];
+ return $self;
+ }
+
+ my $self = Future->_new_convergent( \@subs );
+
+ # Look for immediate fail
+ my $immediate_fail;
+ foreach my $sub ( @subs ) {
+ $sub->{ready} and $sub->{failure} and $immediate_fail = $sub, last;
+ }
+
+ if( $immediate_fail ) {
+ foreach my $sub ( @subs ) {
+ $sub->{ready} or $sub->cancel;
+ }
+
+ $self->{failure} = [ $immediate_fail->failure ];
+ $self->_mark_ready( "needs_all" );
+ return $self;
+ }
+
+ my $pending = 0;
+ $_->{ready} or $pending++ for @subs;
+
+ # Look for immediate done
+ if( !$pending ) {
+ $self->{result} = [ map { $_->get } @subs ];
+ $self->_mark_ready( "needs_all" );
+ return $self;
+ }
+
+ weaken( my $weakself = $self );
+ my $sub_on_ready = sub {
+ return unless $weakself;
+ return if $weakself->{result} or $weakself->{failure}; # don't recurse on child ->cancel
+
+ if( $_[0]->{cancelled} ) {
+ $weakself->{failure} = [ "A component future was cancelled" ];
+ foreach my $sub ( @subs ) {
+ $sub->cancel if !$sub->{ready};
+ }
+ $weakself->_mark_ready( "needs_all" );
+ }
+ elsif( my @failure = $_[0]->failure ) {
+ $weakself->{failure} = \@failure;
+ foreach my $sub ( @subs ) {
+ $sub->cancel if !$sub->{ready};
+ }
+ $weakself->_mark_ready( "needs_all" );
+ }
+ else {
+ $pending--;
+ $pending and return;
+
+ $weakself->{result} = [ map { $_->get } @subs ];
+ $weakself->_mark_ready( "needs_all" );
+ }
+ };
+
+ foreach my $sub ( @subs ) {
+ $sub->{ready} or $sub->on_ready( $sub_on_ready );
+ }
+
+ return $self;
+}
+
+=head2 $future = Future->needs_any( @subfutures )
+
+Returns a new C<Future> instance that will indicate it is ready once any of
+the sub future objects given to it indicate that they have completed
+successfully, or when all of them indicate that they have failed. If any sub
+future succeeds, then this will succeed immediately, and the remaining subs
+not yet ready will be cancelled. Any component futures that are cancelled are
+ignored, apart from the final component left; at which point the result will
+be a failure.
+
+If successful, its result will be that of the first component future that
+succeeded. If it fails, its failure will be that of the last component future
+to fail. To access the other failures, use C<failed_futures>.
+
+Normally when this future completes successfully, only one of its component
+futures will be done. If it is constructed with multiple that are already done
+however, then all of these will be returned from C<done_futures>. Users should
+be careful to still check all the results from C<done_futures> in that case.
+
+When given an empty list this constructor returns an immediately-failed
+future.
+
+This constructor would primarily be used by users of asynchronous interfaces.
+
+=cut
+
+sub needs_any
+{
+ my $class = shift;
+ my @subs = @_;
+
+ unless( @subs ) {
+ my $self = $class->fail( "Cannot ->needs_any with no subfutures" );
+ $self->{subs} = [];
+ return $self;
+ }
+
+ my $self = Future->_new_convergent( \@subs );
+
+ # Look for immediate done
+ my $immediate_done;
+ my $pending = 0;
+ foreach my $sub ( @subs ) {
+ $sub->{ready} and !$sub->{failure} and $immediate_done = $sub, last;
+ $sub->{ready} or $pending++;
+ }
+
+ if( $immediate_done ) {
+ foreach my $sub ( @subs ) {
+ $sub->{ready} ? $sub->{reported} = 1 : $sub->cancel;
+ }
+
+ $self->{result} = [ $immediate_done->get ];
+ $self->_mark_ready( "needs_any" );
+ return $self;
+ }
+
+ # Look for immediate fail
+ my $immediate_fail = 1;
+ foreach my $sub ( @subs ) {
+ $sub->{ready} or $immediate_fail = 0, last;
+ }
+
+ if( $immediate_fail ) {
+ $_->{reported} = 1 for @subs;
+ # For consistency we'll pick the last one for the failure
+ $self->{failure} = [ $subs[-1]->{failure} ];
+ $self->_mark_ready( "needs_any" );
+ return $self;
+ }
+
+ weaken( my $weakself = $self );
+ my $sub_on_ready = sub {
+ return unless $weakself;
+ return if $weakself->{result} or $weakself->{failure}; # don't recurse on child ->cancel
+
+ return if --$pending and $_[0]->{cancelled};
+
+ if( $_[0]->{cancelled} ) {
+ $weakself->{failure} = [ "All component futures were cancelled" ];
+ $weakself->_mark_ready( "needs_any" );
+ }
+ elsif( my @failure = $_[0]->failure ) {
+ $pending and return;
+
+ $weakself->{failure} = \@failure;
+ $weakself->_mark_ready( "needs_any" );
+ }
+ else {
+ $weakself->{result} = [ $_[0]->get ];
+ foreach my $sub ( @subs ) {
+ $sub->cancel if !$sub->{ready};
+ }
+ $weakself->_mark_ready( "needs_any" );
+ }
+ };
+
+ foreach my $sub ( @subs ) {
+ $sub->{ready} or $sub->on_ready( $sub_on_ready );
+ }
+
+ return $self;
+}
+
+=head1 METHODS ON CONVERGENT FUTURES
+
+The following methods apply to convergent (i.e. non-leaf) futures, to access
+the component futures stored by it.
+
+=cut
+
+=head2 @f = $future->pending_futures
+
+=head2 @f = $future->ready_futures
+
+=head2 @f = $future->done_futures
+
+=head2 @f = $future->failed_futures
+
+=head2 @f = $future->cancelled_futures
+
+Return a list of all the pending, ready, done, failed, or cancelled
+component futures. In scalar context, each will yield the number of such
+component futures.
+
+=cut
+
+sub pending_futures
+{
+ my $self = shift;
+ $self->{subs} or Carp::croak "Cannot call ->pending_futures on a non-convergent Future";
+ return grep { not $_->{ready} } @{ $self->{subs} };
+}
+
+sub ready_futures
+{
+ my $self = shift;
+ $self->{subs} or Carp::croak "Cannot call ->ready_futures on a non-convergent Future";
+ return grep { $_->{ready} } @{ $self->{subs} };
+}
+
+sub done_futures
+{
+ my $self = shift;
+ $self->{subs} or Carp::croak "Cannot call ->done_futures on a non-convergent Future";
+ return grep { $_->{ready} and not $_->{failure} and not $_->{cancelled} } @{ $self->{subs} };
+}
+
+sub failed_futures
+{
+ my $self = shift;
+ $self->{subs} or Carp::croak "Cannot call ->failed_futures on a non-convergent Future";
+ return grep { $_->{ready} and $_->{failure} } @{ $self->{subs} };
+}
+
+sub cancelled_futures
+{
+ my $self = shift;
+ $self->{subs} or Carp::croak "Cannot call ->cancelled_futures on a non-convergent Future";
+ return grep { $_->{ready} and $_->{cancelled} } @{ $self->{subs} };
+}
+
+=head1 TRACING METHODS
+
+=head2 $future = $future->set_label( $label )
+
+=head2 $label = $future->label
+
+Chaining mutator and accessor for the label of the C<Future>. This should be a
+plain string value, whose value will be stored by the future instance for use
+in debugging messages or other tooling, or similar purposes.
+
+=cut
+
+sub set_label
+{
+ my $self = shift;
+ ( $self->{label} ) = @_;
+ return $self;
+}
+
+sub label
+{
+ my $self = shift;
+ return $self->{label};
+}
+
+sub __selfstr
+{
+ my $self = shift;
+ return "$self" unless defined $self->{label};
+ return "$self (\"$self->{label}\")";
+}
+
+=head2 [ $sec, $usec ] = $future->btime
+
+=head2 [ $sec, $usec ] = $future->rtime
+
+Accessors that return the tracing timestamps from the instance. These give the
+time the instance was contructed ("birth" time, C<btime>) and the time the
+result was determined (the "ready" time, C<rtime>). Each result is returned as
+a two-element ARRAY ref, containing the epoch time in seconds and
+microseconds, as given by C<Time::HiRes::gettimeofday>.
+
+In order for these times to be captured, they have to be enabled by setting
+C<$Future::TIMES> to a true value. This is initialised true at the time the
+module is loaded if either C<PERL_FUTURE_DEBUG> or C<PERL_FUTURE_TIMES> are
+set in the environment.
+
+=cut
+
+sub btime
+{
+ my $self = shift;
+ return $self->{btime};
+}
+
+sub rtime
+{
+ my $self = shift;
+ return $self->{rtime};
+}
+
+=head2 $sec = $future->elapsed
+
+If both tracing timestamps are defined, returns the number of seconds of
+elapsed time between them as a floating-point number. If not, returns
+C<undef>.
+
+=cut
+
+sub elapsed
+{
+ my $self = shift;
+ return undef unless defined $self->{btime} and defined $self->{rtime};
+ return $self->{elapsed} ||= tv_interval( $self->{btime}, $self->{rtime} );
+}
+
+=head2 $cb = $future->wrap_cb( $operation_name, $cb )
+
+I<Since version 0.31.>
+
+I<Note: This method is experimental and may be changed or removed in a later
+version.>
+
+This method is invoked internally by various methods that are about to save a
+callback CODE reference supplied by the user, to be invoked later. The default
+implementation simply returns the callback agument as-is; the method is
+provided to allow users to provide extra behaviour. This can be done by
+applying a method modifier of the C<around> kind, so in effect add a chain of
+wrappers. Each wrapper can then perform its own wrapping logic of the
+callback. C<$operation_name> is a string giving the reason for which the
+callback is being saved; currently one of C<on_ready>, C<on_done>, C<on_fail>
+or C<sequence>; the latter being used for all the sequence-returning methods.
+
+This method is intentionally invoked only for CODE references that are being
+saved on a pending C<Future> instance to be invoked at some later point. It
+does not run for callbacks to be invoked on an already-complete instance. This
+is for performance reasons, where the intended behaviour is that the wrapper
+can provide some amount of context save and restore, to return the operating
+environment for the callback back to what it was at the time it was saved.
+
+For example, the following wrapper saves the value of a package variable at
+the time the callback was saved, and restores that value at invocation time
+later on. This could be useful for preserving context during logging in a
+Future-based program.
+
+ our $LOGGING_CTX;
+
+ no warnings 'redefine';
+
+ my $orig = Future->can( "wrap_cb" );
+ *Future::wrap_cb = sub {
+ my $cb = $orig->( @_ );
+
+ my $saved_logging_ctx = $LOGGING_CTX;
+
+ return sub {
+ local $LOGGING_CTX = $saved_logging_ctx;
+ $cb->( @_ );
+ };
+ };
+
+At this point, any code deferred into a C<Future> by any of its callbacks will
+observe the C<$LOGGING_CTX> variable as having the value it held at the time
+the callback was saved, even if it is invoked later on when that value is
+different.
+
+Remember when writing such a wrapper, that it still needs to invoke the
+previous version of the method, so that it plays nicely in combination with
+others (see the C<< $orig->( @_ ) >> part).
+
+=cut
+
+sub wrap_cb
+{
+ my $self = shift;
+ my ( $op, $cb ) = @_;
+ return $cb;
+}
+
+=head1 EXAMPLES
+
+The following examples all demonstrate possible uses of a C<Future>
+object to provide a fictional asynchronous API.
+
+For more examples, comparing the use of C<Future> with regular call/return
+style Perl code, see also L<Future::Phrasebook>.
+
+=head2 Providing Results
+
+By returning a new C<Future> object each time the asynchronous function is
+called, it provides a placeholder for its eventual result, and a way to
+indicate when it is complete.
+
+ sub foperation
+ {
+ my %args = @_;
+
+ my $future = Future->new;
+
+ do_something_async(
+ foo => $args{foo},
+ on_done => sub { $future->done( @_ ); },
+ );
+
+ return $future;
+ }
+
+In most cases, the C<done> method will simply be invoked with the entire
+result list as its arguments. In that case, it is simpler to use the
+C<done_cb> wrapper method to create the C<CODE> reference.
+
+ my $future = Future->new;
+
+ do_something_async(
+ foo => $args{foo},
+ on_done => $future->done_cb,
+ );
+
+The caller may then use this future to wait for a result using the C<on_ready>
+method, and obtain the result using C<get>.
+
+ my $f = foperation( foo => "something" );
+
+ $f->on_ready( sub {
+ my $f = shift;
+ say "The operation returned: ", $f->get;
+ } );
+
+=head2 Indicating Success or Failure
+
+Because the stored exception value of a failed future may not be false, the
+C<failure> method can be used in a conditional statement to detect success or
+failure.
+
+ my $f = foperation( foo => "something" );
+
+ $f->on_ready( sub {
+ my $f = shift;
+ if( not my $e = $f->failure ) {
+ say "The operation succeeded with: ", $f->get;
+ }
+ else {
+ say "The operation failed with: ", $e;
+ }
+ } );
+
+By using C<not> in the condition, the order of the C<if> blocks can be
+arranged to put the successful case first, similar to a C<try>/C<catch> block.
+
+Because the C<get> method re-raises the passed exception if the future failed,
+it can be used to control a C<try>/C<catch> block directly. (This is sometimes
+called I<Exception Hoisting>).
+
+ use Try::Tiny;
+
+ $f->on_ready( sub {
+ my $f = shift;
+ try {
+ say "The operation succeeded with: ", $f->get;
+ }
+ catch {
+ say "The operation failed with: ", $_;
+ };
+ } );
+
+Even neater still may be the separate use of the C<on_done> and C<on_fail>
+methods.
+
+ $f->on_done( sub {
+ my @result = @_;
+ say "The operation succeeded with: ", @result;
+ } );
+ $f->on_fail( sub {
+ my ( $failure ) = @_;
+ say "The operation failed with: $failure";
+ } );
+
+=head2 Immediate Futures
+
+Because the C<done> method returns the future object itself, it can be used to
+generate a C<Future> that is immediately ready with a result. This can also be
+used as a class method.
+
+ my $f = Future->done( $value );
+
+Similarly, the C<fail> and C<die> methods can be used to generate a C<Future>
+that is immediately failed.
+
+ my $f = Future->die( "This is never going to work" );
+
+This could be considered similarly to a C<die> call.
+
+An C<eval{}> block can be used to turn a C<Future>-returning function that
+might throw an exception, into a C<Future> that would indicate this failure.
+
+ my $f = eval { function() } || Future->fail( $@ );
+
+This is neater handled by the C<call> class method, which wraps the call in
+an C<eval{}> block and tests the result:
+
+ my $f = Future->call( \&function );
+
+=head2 Sequencing
+
+The C<then> method can be used to create simple chains of dependent tasks,
+each one executing and returning a C<Future> when the previous operation
+succeeds.
+
+ my $f = do_first()
+ ->then( sub {
+ return do_second();
+ })
+ ->then( sub {
+ return do_third();
+ });
+
+The result of the C<$f> future itself will be the result of the future
+returned by the final function, if none of them failed. If any of them fails
+it will fail with the same failure. This can be considered similar to normal
+exception handling in synchronous code; the first time a function call throws
+an exception, the subsequent calls are not made.
+
+=head2 Merging Control Flow
+
+A C<wait_all> future may be used to resynchronise control flow, while waiting
+for multiple concurrent operations to finish.
+
+ my $f1 = foperation( foo => "something" );
+ my $f2 = foperation( bar => "something else" );
+
+ my $f = Future->wait_all( $f1, $f2 );
+
+ $f->on_ready( sub {
+ say "Operations are ready:";
+ say " foo: ", $f1->get;
+ say " bar: ", $f2->get;
+ } );
+
+This provides an ability somewhat similar to C<CPS::kpar()> or
+L<Async::MergePoint>.
+
+=cut
+
+=head1 KNOWN ISSUES
+
+=head2 Cancellation of Non-Final Sequence Futures
+
+The behaviour of future cancellation still has some unanswered questions
+regarding how to handle the situation where a future is cancelled that has a
+sequence future constructed from it.
+
+In particular, it is unclear in each of the following examples what the
+behaviour of C<$f2> should be, were C<$f1> to be cancelled:
+
+ $f2 = $f1->then( sub { ... } ); # plus related ->then_with_f, ...
+
+ $f2 = $f1->else( sub { ... } ); # plus related ->else_with_f, ...
+
+ $f2 = $f1->followed_by( sub { ... } );
+
+In the C<then>-style case it is likely that this situation should be treated
+as if C<$f1> had failed, perhaps with some special message. The C<else>-style
+case is more complex, because it may be that the entire operation should still
+fail, or it may be that the cancellation of C<$f1> should again be treated
+simply as a special kind of failure, and the C<else> logic run as normal.
+
+To be specific; in each case it is unclear what happens if the first future is
+cancelled, while the second one is still waiting on it. The semantics for
+"normal" top-down cancellation of C<$f2> and how it affects C<$f1> are already
+clear and defined.
+
+=head2 Cancellation of Divergent Flow
+
+A further complication of cancellation comes from the case where a given
+future is reused multiple times for multiple sequences or convergent trees.
+
+In particular, it is in clear in each of the following examples what the
+behaviour of C<$f2> should be, were C<$f1> to be cancelled:
+
+ my $f_initial = Future->new; ...
+ my $f1 = $f_initial->then( ... );
+ my $f2 = $f_initial->then( ... );
+
+ my $f1 = Future->needs_all( $f_initial );
+ my $f2 = Future->needs_all( $f_initial );
+
+The point of cancellation propagation is to trace backwards through stages of
+some larger sequence of operations that now no longer need to happen, because
+the final result is no longer required. But in each of these cases, just
+because C<$f1> has been cancelled, the initial future C<$f_initial> is still
+required because there is another future (C<$f2>) that will still require its
+result.
+
+Initially it would appear that some kind of reference-counting mechanism could
+solve this question, though that itself is further complicated by the
+C<on_ready> handler and its variants.
+
+It may simply be that a comprehensive useful set of cancellation semantics
+can't be universally provided to cover all cases; and that some use-cases at
+least would require the application logic to give extra information to its
+C<Future> objects on how they should wire up the cancel propagation logic.
+
+Both of these cancellation issues are still under active design consideration;
+see the discussion on RT96685 for more information
+(L<https://rt.cpan.org/Ticket/Display.html?id=96685>).
+
+=cut
+
+=head1 SEE ALSO
+
+=over 4
+
+=item *
+
+L<curry> - Create automatic curried method call closures for any class or
+object
+
+=item *
+
+"The Past, The Present and The Future" - slides from a talk given at the
+London Perl Workshop, 2012.
+
+L<https://docs.google.com/presentation/d/1UkV5oLcTOOXBXPh8foyxko4PR28_zU_aVx6gBms7uoo/edit>
+
+=item *
+
+"Futures advent calendar 2013"
+
+L<http://leonerds-code.blogspot.co.uk/2013/12/futures-advent-day-1.html>
+
+=back
+
+=cut
+
+=head1 TODO
+
+=over 4
+
+=item *
+
+Consider the ability to pass the constructor an C<await> CODEref, instead of
+needing to use a subclass. This might simplify async/etc.. implementations,
+and allows the reuse of the idea of subclassing to extend the abilities of
+C<Future> itself - for example to allow a kind of Future that can report
+incremental progress.
+
+=back
+
+=cut
+
+=head1 AUTHOR
+
+Paul Evans <leonerd@leonerd.org.uk>
+
+=cut
+
+0x55AA;