Subject: | Support for Future-returning $loop->later |
I figured it might be nice if this worked:
await $loop->later;
and the code seemed easy enough to implement without breaking anything...
Subject: | loop-later.patch |
diff --git a/lib/IO/Async/Loop.pm b/lib/IO/Async/Loop.pm
index 0cfac00..17eee45 100644
--- a/lib/IO/Async/Loop.pm
+++ b/lib/IO/Async/Loop.pm
@@ -886,6 +886,11 @@ This method is implemented using the C<watch_idle> method, with the C<when>
parameter set to C<later>. It will return an ID value that can be passed to
C<unwatch_idle> if required.
+If no C<< $code >> value is passed, a L<Future> will be returned instead.
+This allows for constructs such as:
+
+ await $loop->later;
+
=cut
sub later
@@ -893,7 +898,17 @@ sub later
my $self = shift;
my ( $code ) = @_;
- return $self->watch_idle( when => 'later', code => $code );
+ return $self->watch_idle( when => 'later', code => $code )
+ if $code;
+
+ my $f = $self->new_future;
+ my $id = $self->watch_idle( when => 'later', code => sub {
+ $f->done unless $f->is_ready;
+ } );
+ $f->on_cancel( sub {
+ $self->unwatch_idle( $id );
+ } );
+ return $f;
}
=head2 spawn_child
diff --git a/t/19loop-future.t b/t/19loop-future.t
index 25c3e98..740eb56 100644
--- a/t/19loop-future.t
+++ b/t/19loop-future.t
@@ -29,6 +29,18 @@ my $loop = IO::Async::Loop->new_builtin;
is_deeply( [ $future->get ], [ "result" ], '$future->get' );
}
+{
+ my $future = $loop->later;
+ my $cancellable_future = $loop->later;
+
+ ok(!$future->is_ready, '$loop->later returns a pending Future');
+ ok(!$cancellable_future->is_ready, 'another $loop->later also returns a pending Future');
+ $cancellable_future->cancel;
+ $loop->loop_once;
+ ok($future->is_done, '$loop->later Future is resolved after one loop iteration');
+ ok($cancellable_future->is_cancelled, '$loop->later Future cancels cleanly');
+}
+
{
my @futures = map { Future->new } 0 .. 2;