Future
view release on metacpan or search on metacpan
0.48 2022-01-26
[CHANGES]
* Implement the new AWAIT_ON_CANCEL API shape for Future::AsyncAwait
[BUGFIXES]
* Make sure to set rtime for immediate futures (RT134620)
0.47 2021-01-01
[BUGFIXES]
* Don't weaken() the waiting future in Future::Mutex as that causes
it to be dropped in some situations
0.46 2020-10-19
[CHANGES]
* Provide AWAIT_CHAIN_CANCEL named method for compatibility with
upcoming Future::AsyncAwait::Awaitable method rename
[BUGFIXES]
* Ensure that Future::Mutex returns proper cloned future instances
when waiting (RT133563)
0.26 2014/06/01 12:52:53
[CHANGES]
* Added ->is_failed accessor
* Implement ->export_to_level in Future::Utils
* Print a warning about lost sequence Futures
* Allow Future->done and Future->fail as simple class constructors
to return immediates
* Added Future->unwrap
[BUGFIXES]
* Ensure that sequence futures are weaken()ed in the forward
direction.
**NOTE** This will potentially break existing code that depended on
strong references. This old code was, however, broken.
0.25 2014/02/22 03:47:08
[BUGFIXES]
* Fix warning-matching test in unit test for both older and newer
versions of Carp
0.24 2014/02/21 17:57:49
lib/Future/PP.pm view on Meta::CPAN
package Future::PP 0.51;
use v5.14;
use warnings;
no warnings 'recursion'; # Disable the "deep recursion" warning
our @ISA = qw( Future::_base );
use Carp qw(); # don't import croak
use List::Util 1.29 qw( pairs pairkeys );
use Scalar::Util qw( weaken blessed reftype );
use Time::HiRes qw( gettimeofday );
our @CARP_NOT = qw( Future Future::_base Future::Utils );
use constant DEBUG => !!$ENV{PERL_FUTURE_DEBUG};
use constant STRICT => !!$ENV{PERL_FUTURE_STRICT};
# Callback flags
use constant {
lib/Future/PP.pm view on Meta::CPAN
$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
lib/Future/PP.pm view on Meta::CPAN
}
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 : () ),
);
}
}
}
lib/Future/PP.pm view on Meta::CPAN
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;
if( $is_future ) {
push @{ $code->{revoke_when_ready} }, my $r = [ $self, \$self->{on_cancel}[-1] ];
weaken( $r->[0] );
weaken( $r->[1] );
}
return $self;
}
# An optimised version for Awaitable role
sub AWAIT_ON_CANCEL
{
my $self = shift;
my ( $code ) = @_;
lib/Future/PP.pm view on Meta::CPAN
push @{ $self->{on_cancel} }, $code;
}
sub AWAIT_CHAIN_CANCEL
{
my $self = shift;
my ( $f2 ) = @_;
push @{ $self->{on_cancel} }, $f2;
push @{ $f2->{revoke_when_ready} }, my $r = [ $self, \$self->{on_cancel}[-1] ];
weaken( $r->[0] );
weaken( $r->[1] );
}
sub _revoke_on_cancel
{
my $self = shift;
my ( $ref ) = @_;
undef $$ref;
$self->{empty_on_cancel_slots}++;
lib/Future/PP.pm view on Meta::CPAN
}
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;
}
sub then
{
my $self = shift;
my $done_code = shift;
my $fail_code = ( @_ % 2 ) ? pop : undef;
my @catch_list = @_;
lib/Future/PP.pm view on Meta::CPAN
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 my $self = $weakself;
$pending--;
$pending and return;
$self->{result} = [ pairkeys @{ $self->{subs} } ];
$self->_mark_ready( "wait_all" );
};
lib/Future/PP.pm view on Meta::CPAN
}
else {
$self->{result} = [ @{ $immediate_ready->{result} } ];
}
$self->_mark_ready( "wait_any" );
return $self;
}
my $pending = 0;
weaken( my $weakself = $self );
my $sub_on_ready = sub {
return unless my $self = $weakself;
return if $self->{result} or $self->{failure}; # don't recurse on child ->cancel
return if --$pending and $_[0]->{cancelled};
if( $_[0]->{cancelled} ) {
$self->{failure} = [ "All component futures were cancelled" ];
}
elsif( $_[0]->{failure} ) {
lib/Future/PP.pm view on Meta::CPAN
my $pending = 0;
$_->{ready} or $pending++ for @subs;
# Look for immediate done
if( !$pending ) {
$self->{result} = [ map { @{ $_->{result} } } @subs ];
$self->_mark_ready( "needs_all" );
return $self;
}
weaken( my $weakself = $self );
my $sub_on_ready = sub {
return unless my $self = $weakself;
return if $self->{result} or $self->{failure}; # don't recurse on child ->cancel
if( $_[0]->{cancelled} ) {
$self->{failure} = [ "A component future was cancelled" ];
$self->_cancel_subs;
$self->_mark_ready( "needs_all" );
}
elsif( $_[0]->{failure} ) {
lib/Future/PP.pm view on Meta::CPAN
}
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 my $self = $weakself;
return if $self->{result} or $self->{failure}; # don't recurse on child ->cancel
return if --$pending and $_[0]->{cancelled};
if( $_[0]->{cancelled} ) {
$self->{failure} = [ "All component futures were cancelled" ];
$self->_mark_ready( "needs_any" );
}
( run in 0.459 second using v1.01-cache-2.11-cpan-1f129e94a17 )