File Coverage

blib/lib/Future/Mojo.pm
Criterion Covered Total %
statement 57 57 100.0
branch 13 20 65.0
condition 5 9 55.5
subroutine 20 20 100.0
pod 7 7 100.0
total 102 113 90.2


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