Future-Mojo
view release on metacpan or search on metacpan
lib/Future/Mojo.pm view on Meta::CPAN
package Future::Mojo;
use strict;
use warnings;
use Carp 'croak';
use Scalar::Util 'blessed', 'weaken';
use Mojo::IOLoop;
use Role::Tiny::With;
use parent 'Future';
our $VERSION = '1.003';
with 'Future::Role::Promisify';
sub new {
my $proto = shift;
my $self = $proto->SUPER::new;
my $loop = ref $proto ? $proto->loop : (shift() // Mojo::IOLoop->singleton);
$self->set_udata(loop => $loop);
return $self;
}
sub new_timer {
my $proto = shift;
my $self = (blessed $_[0] and $_[0]->isa('Mojo::IOLoop'))
? $proto->new(shift) : $proto->new;
$self->_set_timer(1, @_);
return $self;
}
sub new_timeout {
my $proto = shift;
my $self = (blessed $_[0] and $_[0]->isa('Mojo::IOLoop'))
? $proto->new(shift) : $proto->new;
$self->_set_timer(0, @_);
return $self;
}
sub _set_timer {
my ($self, $succeed, $after) = @_;
weaken(my $weakself = $self);
my $cb = $succeed ? sub { $weakself->done if $weakself }
: sub { $weakself->fail('Timeout') if $weakself };
my $id = $self->loop->timer($after => $cb);
$self->on_cancel(sub { shift->loop->remove($id) });
return $self;
}
sub loop { shift->udata('loop') }
sub await {
my $self = shift;
croak 'Awaiting a future while the event loop is running would recurse'
if $self->loop->is_running;
$self->loop->one_tick until $self->is_ready;
}
sub done_next_tick {
weaken(my $self = shift);
my @result = @_;
$self->loop->next_tick(sub { $self->done(@result) if $self });
return $self;
}
sub fail_next_tick {
weaken(my $self = shift);
my ($exception, @details) = @_;
croak 'Expected a true exception' unless $exception;
$self->loop->next_tick(sub { $self->fail($exception, @details) if $self });
return $self;
}
1;
=head1 NAME
Future::Mojo - use Future with Mojo::IOLoop
=head1 SYNOPSIS
use Future::Mojo;
use Mojo::IOLoop;
my $loop = Mojo::IOLoop->new;
my $future = Future::Mojo->new($loop);
$loop->timer(3 => sub { $future->done('Done') });
print $future->get, "\n";
=head1 DESCRIPTION
This subclass of L<Future> stores a reference to the associated L<Mojo::IOLoop>
instance, allowing the C<await> method to block until the Future is ready.
For a full description on how to use Futures, see the L<Future> documentation.
=head1 CONSTRUCTORS
=head2 new
my $future = Future::Mojo->new;
my $future = Future::Mojo->new($loop);
Returns a new Future. Uses L<Mojo::IOLoop/"singleton"> if no loop is specified.
=head2 new_timer
my $future = Future::Mojo->new_timer($seconds);
my $future = Future::Mojo->new_timer($loop, $seconds);
Returns a new Future that will become ready after the specified delay. Uses
L<Mojo::IOLoop/"singleton"> if no loop is specified.
=head2 new_timeout
my $future = Future::Mojo->new_timeout($seconds);
my $future = Future::Mojo->new_timeout($loop, $seconds);
Returns a new Future that will fail after the specified delay. Uses
L<Mojo::IOLoop/"singleton"> if no loop is specified.
( run in 1.408 second using v1.01-cache-2.11-cpan-d8267643d1d )