File Coverage

blib/lib/Future/Mojo.pm
Criterion Covered Total %
statement 58 58 100.0
branch 13 20 65.0
condition 5 9 55.5
subroutine 20 20 100.0
pod 7 7 100.0
total 103 114 90.3


line stmt bran cond sub pod time code
1             package Future::Mojo;
2              
3 3     3   837110 use strict;
  3         6  
  3         109  
4 3     3   26 use warnings;
  3         20  
  3         138  
5 3     3   14 use Carp 'croak';
  3         6  
  3         142  
6 3     3   13 use Scalar::Util 'blessed', 'weaken';
  3         5  
  3         123  
7 3     3   1194 use Mojo::IOLoop;
  3         783132  
  3         16  
8 3     3   1384 use Role::Tiny::With;
  3         810  
  3         159  
9              
10 3     3   17 use parent 'Future';
  3         5  
  3         27  
11              
12             our $VERSION = '1.003';
13              
14             with 'Future::Role::Promisify';
15              
16             sub new {
17 25     25 1 692310 my $proto = shift;
18 25         154 my $self = $proto->SUPER::new;
19            
20 25 50 66     337 my $loop = ref $proto ? $proto->loop : (shift() // Mojo::IOLoop->singleton);
21 25         184 $self->set_udata(loop => $loop);
22            
23 25         268 return $self;
24             }
25              
26             sub new_timer {
27 10     10 1 8942 my $proto = shift;
28 10 100 66     132 my $self = (blessed $_[0] and $_[0]->isa('Mojo::IOLoop'))
29             ? $proto->new(shift) : $proto->new;
30            
31 10         41 $self->_set_timer(1, @_);
32            
33 10         62 return $self;
34             }
35              
36             sub new_timeout {
37 1     1 1 1619 my $proto = shift;
38 1 50 33     19 my $self = (blessed $_[0] and $_[0]->isa('Mojo::IOLoop'))
39             ? $proto->new(shift) : $proto->new;
40            
41 1         6 $self->_set_timer(0, @_);
42            
43 1         4 return $self;
44             }
45              
46             sub _set_timer {
47 11     11   29 my ($self, $succeed, $after) = @_;
48            
49 11         26 weaken(my $weakself = $self);
50 4 50   4   802083 my $cb = $succeed ? sub { $weakself->done if $weakself }
51 11 50   1   74 : sub { $weakself->fail('Timeout') if $weakself };
  1 100       100331  
52 11         29 my $id = $self->loop->timer($after => $cb);
53            
54 11     2   1067 $self->on_cancel(sub { shift->loop->remove($id) });
  2         132  
55            
56 11         257 return $self;
57             }
58              
59 54     54 1 247 sub loop { shift->udata('loop') }
60              
61             sub await {
62 15     15 1 2907 my $self = shift;
63 15 100       64 croak 'Awaiting a future while the event loop is running would recurse'
64             if $self->loop->is_running;
65 13         365 $self->loop->one_tick until $self->is_ready;
66             }
67              
68             sub done_next_tick {
69 4     4 1 18 weaken(my $self = shift);
70 4         39 my @result = @_;
71            
72 4 50   4   15 $self->loop->next_tick(sub { $self->done(@result) if $self });
  4         429  
73            
74 4         324 return $self;
75             }
76              
77             sub fail_next_tick {
78 2     2 1 14 weaken(my $self = shift);
79 2         7 my ($exception, @details) = @_;
80            
81 2 50       41 croak 'Expected a true exception' unless $exception;
82            
83 2 50   2   10 $self->loop->next_tick(sub { $self->fail($exception, @details) if $self });
  2         284  
84            
85 2         211 return $self;
86             }
87              
88             1;
89              
90             =head1 NAME
91              
92             Future::Mojo - use Future with Mojo::IOLoop
93              
94             =head1 SYNOPSIS
95              
96             use Future::Mojo;
97             use Mojo::IOLoop;
98            
99             my $loop = Mojo::IOLoop->new;
100            
101             my $future = Future::Mojo->new($loop);
102            
103             $loop->timer(3 => sub { $future->done('Done') });
104            
105             print $future->get, "\n";
106              
107             =head1 DESCRIPTION
108              
109             This subclass of L stores a reference to the associated L
110             instance, allowing the C method to block until the Future is ready.
111              
112             For a full description on how to use Futures, see the L documentation.
113              
114             =head1 CONSTRUCTORS
115              
116             =head2 new
117              
118             my $future = Future::Mojo->new;
119             my $future = Future::Mojo->new($loop);
120              
121             Returns a new Future. Uses L if no loop is specified.
122              
123             =head2 new_timer
124              
125             my $future = Future::Mojo->new_timer($seconds);
126             my $future = Future::Mojo->new_timer($loop, $seconds);
127              
128             Returns a new Future that will become ready after the specified delay. Uses
129             L if no loop is specified.
130              
131             =head2 new_timeout
132              
133             my $future = Future::Mojo->new_timeout($seconds);
134             my $future = Future::Mojo->new_timeout($loop, $seconds);
135              
136             Returns a new Future that will fail after the specified delay. Uses
137             L if no loop is specified.
138              
139             =head1 METHODS
140              
141             L inherits all methods from L and implements the
142             following new ones.
143              
144             =head2 loop
145              
146             $loop = $future->loop;
147              
148             Returns the underlying L object.
149              
150             =head2 await
151              
152             $future->await;
153              
154             Runs the underlying L until the future is ready. If the event
155             loop is already running, an exception is thrown.
156              
157             =head2 done_next_tick
158              
159             $future = $future->done_next_tick(@result);
160              
161             A shortcut to calling the L method on the
162             L. Ensures that a returned Future object is not ready
163             immediately, but will wait for the next I/O round.
164              
165             =head2 fail_next_tick
166              
167             $future = $future->fail_next_tick($exception, @details);
168              
169             A shortcut to calling the L method on the
170             L. Ensures that a returned Future object is not ready
171             immediately, but will wait for the next I/O round.
172              
173             =head2 promisify
174              
175             my $promise = $future->promisify;
176              
177             Composed from L.
178              
179             =head1 BUGS
180              
181             Report any issues on the public bugtracker.
182              
183             =head1 AUTHOR
184              
185             Dan Book
186              
187             =head1 CONTRIBUTORS
188              
189             =over
190              
191             =item Jose Luis Martinez (pplu)
192              
193             =back
194              
195             =head1 COPYRIGHT AND LICENSE
196              
197             This software is Copyright (c) 2015 by Dan Book.
198              
199             This is free software, licensed under:
200              
201             The Artistic License 2.0 (GPL Compatible)
202              
203             =head1 SEE ALSO
204              
205             L