File Coverage

blib/lib/Object/Remote/Future.pm
Criterion Covered Total %
statement 63 80 78.7
branch 13 18 72.2
condition 7 12 58.3
subroutine 14 20 70.0
pod 0 3 0.0
total 97 133 72.9


line stmt bran cond sub pod time code
1             package Object::Remote::Future;
2              
3 15     15   88 use strict;
  15         26  
  15         363  
4 15     15   61 use warnings;
  15         22  
  15         344  
5 15     15   63 use base qw(Exporter);
  15         21  
  15         1407  
6              
7 15     15   80 use Object::Remote::Logging qw( :log router );
  15         26  
  15         71  
8              
9 15     15   64 BEGIN { router()->exclude_forwarding }
10              
11 15     15   8602 use Future;
  15         121682  
  15         11525  
12              
13             our @EXPORT = qw(future await_future await_all);
14              
15             sub future (&;$) {
16 136     136 0 968 my $f = $_[0]->(Future->new);
17 136 100 50     1852 return $f if ((caller(1+($_[1]||0))||'') eq 'start');
18 110         337 await_future($f);
19             }
20              
21             our @await;
22              
23             sub await_future {
24 175     175 0 1042 my $f = shift;
25 175     0   1458 log_trace { my $ir = $f->is_ready; "await_future() invoked; is_ready: $ir" };
  0         0  
  0         0  
26 175 50       2057 return $f if $f->is_ready;
27 175         1686 require Object::Remote;
28 175         790 my $loop = Object::Remote->current_loop;
29             {
30 175         279 local @await = (@await, $f);
  175         557  
31             $f->on_ready(sub {
32 175     175   3501 log_trace { my $l = @await; "future has become ready, length of \@await: '$l'" };
  0         0  
  0         0  
33 175 50       2408 if ($f == $await[-1]) {
34 175         836 log_trace { "This future is not waiting on anything so calling stop on the run loop" };
  0         0  
35 175         3797 $loop->stop;
36             }
37 175         1217 });
38 175     0   4207 log_trace { "Starting run loop for newly created future" };
  0         0  
39 175         2021 $loop->run;
40             }
41 175 100 66     749 if (@await and $await[-1]->is_ready) {
42 57     0   646 log_trace { "Last future in await list was ready, stopping run loop" };
  0         0  
43 57         1196 $loop->stop;
44             }
45 175     0   1151 log_trace { "await_future() returning" };
  0         0  
46 175 100       1865 return wantarray ? $f->get : ($f->get)[0];
47             }
48              
49             sub await_all {
50 0     0 0 0 log_trace { my $l = @_; "await_all() invoked with '$l' futures to wait on" };
  0     2   0  
  2         484  
51 2         52 await_future(Future->wait_all(@_));
52 2         38 map $_->get, @_;
53             }
54              
55             package start;
56              
57             our $start = sub { my ($obj, $call) = (shift, shift); $obj->$call(@_); };
58              
59             sub AUTOLOAD {
60 13     13   1018 my $invocant = shift;
61 13         97 my ($method) = our $AUTOLOAD =~ /^start::(.+)$/;
62 13         27 my $res;
63 13 50       22 unless (eval { $res = $invocant->$method(@_); 1 }) {
  13         61  
  13         90  
64 0         0 my $f = Future->new;
65 0         0 $f->fail($@);
66 0         0 return $f;
67             }
68 13 100 100     105 unless (Scalar::Util::blessed($res) and $res->isa('Future')) {
69 2         9 my $f = Future->new;
70 2         19 $f->done($res);
71 2         99 return $f;
72             }
73 11         41 return $res;
74             }
75              
76             package maybe;
77              
78             sub start {
79 0     0   0 my ($obj, $call) = (shift, shift);
80 0 0 0     0 if ((caller(1)||'') eq 'start') {
81 0         0 $obj->$start::start($call => @_);
82             } else {
83 0         0 $obj->$call(@_);
84             }
85             }
86              
87             package maybe::start;
88              
89             sub AUTOLOAD {
90 48     48   1327 my $invocant = shift;
91 48         310 my ($method) = our $AUTOLOAD =~ /^maybe::start::(.+)$/;
92 48 100 50     243 $method = "start::${method}" if ((caller(1)||'') eq 'start');
93 48         511 $invocant->$method(@_);
94             }
95              
96             package then;
97              
98             sub AUTOLOAD {
99 2     2   3 my $invocant = shift;
100 2         9 my ($method) = our $AUTOLOAD =~ /^then::(.+)$/;
101 2         4 my @args = @_;
102             return $invocant->then(sub {
103 2     2   535 my ($obj) = @_;
104 2         4 return $obj->${\"start::${method}"}(@args);
  2         12  
105 2         12 });
106             }
107              
108             1;
109              
110             =head1 NAME
111              
112             Object::Remote::Future - Asynchronous calling for L
113              
114             =head1 LAME
115              
116             Shipping prioritised over writing this part up. Blame mst.
117              
118             =cut