summaryrefslogtreecommitdiff
path: root/lib/IO/Async/Future.pm
blob: 7e8de42589b7b60c774d320a15584139b9189c83 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#  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, 2013 -- leonerd@leonerd.org.uk

package IO::Async::Future;

use strict;
use warnings;

our $VERSION = '0.78';

use base qw( Future );
Future->VERSION( '0.05' ); # to respect subclassing

use Carp;

=head1 NAME

C<IO::Async::Future> - use L<Future> with L<IO::Async>

=head1 SYNOPSIS

 use IO::Async::Loop;

 my $loop = IO::Async::Loop->new;

 my $future = $loop->new_future;

 $loop->watch_time( after => 3, code => sub { $future->done( "Done" ) } );

 print $future->get, "\n";

=head1 DESCRIPTION

This subclass of L<Future> stores a reference to the L<IO::Async::Loop>
instance that created it, allowing the C<await> method to block until the
Future is ready. These objects should not be constructed directly; instead
the C<new_future> method on the containing Loop should be used.

For a full description on how to use Futures, see the L<Future> documentation.

=cut

=head1 CONSTRUCTORS

New C<IO::Async::Future> objects should be constructed by using the following
methods on the C<Loop>. For more detail see the L<IO::Async::Loop>
documentation.

   $future = $loop->new_future

Returns a new pending Future.

   $future = $loop->delay_future( %args )

Returns a new Future that will become done at a given time.

   $future = $loop->timeout_future( %args )

Returns a new Future that will become failed at a given time.

=cut

sub new
{
   my $proto = shift;
   my $self = $proto->SUPER::new;

   if( ref $proto ) {
      $self->{loop} = $proto->{loop};
   }
   else {
      $self->{loop} = shift;
   }

   return $self;
}

=head1 METHODS

=cut

=head2 loop

   $loop = $future->loop

Returns the underlying L<IO::Async::Loop> object.

=cut

sub loop
{
   my $self = shift;
   return $self->{loop};
}

sub await
{
   my $self = shift;
   $self->{loop}->await( $self );
}

=head2 done_later

   $future->done_later( @result )

A shortcut to calling the C<done> method in a C<later> idle watch on the
underlying Loop object. Ensures that a returned Future object is not ready
immediately, but will wait for the next IO round.

Like C<done>, returns C<$future> itself to allow easy chaining.

=cut

sub done_later
{
   my $self = shift;
   my @result = @_;

   $self->loop->later( sub { $self->done( @result ) } );

   return $self;
}

=head2 fail_later

   $future->fail_later( $exception, @details )

A shortcut to calling the C<fail> method in a C<later> idle watch on the
underlying Loop object. Ensures that a returned Future object is not ready
immediately, but will wait for the next IO round.

Like C<fail>, returns C<$future> itself to allow easy chaining.

=cut

sub fail_later
{
   my $self = shift;
   my ( $exception, @details ) = @_;

   $exception or croak "Expected a true exception";

   $self->loop->later( sub { $self->fail( $exception, @details ) } );

   return $self;
}

=head1 AUTHOR

Paul Evans <leonerd@leonerd.org.uk>

=cut

0x55AA;