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   53 use strict;
  15         16  
  15         328  
4 15     15   45 use warnings;
  15         16  
  15         318  
5 15     15   46 use base qw(Exporter);
  15         14  
  15         1059  
6              
7 15     15   55 use Object::Remote::Logging qw( :log router );
  15         18  
  15         101  
8              
9 15     15   56 BEGIN { router()->exclude_forwarding }
10              
11 15     15   8996 use Future;
  15         88075  
  15         10413  
12              
13             our @EXPORT = qw(future await_future await_all);
14              
15             sub future (&;$) {
16 136     136 0 840 my $f = $_[0]->(Future->new);
17 136 100 50     1948 return $f if ((caller(1+($_[1]||0))||'') eq 'start');
18 110         373 await_future($f);
19             }
20              
21             our @await;
22              
23             sub await_future {
24 175     175 0 833 my $f = shift;
25 175     0   1401 log_trace { my $ir = $f->is_ready; "await_future() invoked; is_ready: $ir" };
  0         0  
  0         0  
26 175 50       2406 return $f if $f->is_ready;
27 175         1900 require Object::Remote;
28 175         1226 my $loop = Object::Remote->current_loop;
29             {
30 175         249 local @await = (@await, $f);
  175         585  
31             $f->on_ready(sub {
32 175     175   3978 log_trace { my $l = @await; "future has become ready, length of \@await: '$l'" };
  0         0  
  0         0  
33 175 50       2894 if ($f == $await[-1]) {
34 175         906 log_trace { "This future is not waiting on anything so calling stop on the run loop" };
  0         0  
35 175         4479 $loop->stop;
36             }
37 175         1175 });
38 175     0   3865 log_trace { "Starting run loop for newly created future" };
  0         0  
39 175         2582 $loop->run;
40             }
41 175 100 66     963 if (@await and $await[-1]->is_ready) {
42 57     0   716 log_trace { "Last future in await list was ready, stopping run loop" };
  0         0  
43 57         1808 $loop->stop;
44             }
45 175     0   1124 log_trace { "await_future() returning" };
  0         0  
46 175 100       2155 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         399  
51 2         56 await_future(Future->wait_all(@_));
52 2         32 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   631 my $invocant = shift;
61 13         67 my ($method) = our $AUTOLOAD =~ /^start::(.+)$/;
62 13         18 my $res;
63 13 50       19 unless (eval { $res = $invocant->$method(@_); 1 }) {
  13         78  
  13         108  
64 0         0 my $f = Future->new;
65 0         0 $f->fail($@);
66 0         0 return $f;
67             }
68 13 100 100     150 unless (Scalar::Util::blessed($res) and $res->isa('Future')) {
69 2         7 my $f = Future->new;
70 2         16 $f->done($res);
71 2         74 return $f;
72             }
73 11         47 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   1189 my $invocant = shift;
91 48         284 my ($method) = our $AUTOLOAD =~ /^maybe::start::(.+)$/;
92 48 100 50     271 $method = "start::${method}" if ((caller(1)||'') eq 'start');
93 48         1312 $invocant->$method(@_);
94             }
95              
96             package then;
97              
98             sub AUTOLOAD {
99 2     2   2 my $invocant = shift;
100 2         7 my ($method) = our $AUTOLOAD =~ /^then::(.+)$/;
101 2         5 my @args = @_;
102             return $invocant->then(sub {
103 2     2   391 my ($obj) = @_;
104 2         2 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