File Coverage

blib/lib/AnyEvent/Delay.pm
Criterion Covered Total %
statement 6 17 35.2
branch n/a
condition n/a
subroutine 2 5 40.0
pod n/a
total 8 22 36.3


line stmt bran cond sub pod time code
1             package AnyEvent::Delay;
2 1     1   32263 use Moo;
  1         27929  
  1         7  
3 1     1   2991 use EV;
  1         3266  
  1         461  
4              
5             our $VERSION = 0.01;
6              
7             has on_error => (
8             is => 'rw',
9             isa => sub {
10             return 2 if ref $_[0] eq 'CODE';
11             },
12             default => sub { sub { 1 } },
13             );
14              
15             has on_finish => (
16             is => 'rw',
17             isa => sub {
18             return 2 if ref $_[0] eq 'CODE';
19             }
20             );
21              
22             sub begin {
23 0     0     my $self = shift;
24 0           my @callar = caller;
25 0           my @mark = @_;
26 0           $self->{pending}++;
27 0           my $id = $self->{_ae_counter}++;
28             return sub {
29 0     0     $self->_step($id, @_, @mark)
30 0           };
31             }
32              
33             sub steps {
34 0     0     my $self = shift;
35 0           $self->{steps} = [@_];
36              
37 0           $self->begin->();
38             #$self->{timers}{-1} = EV::timer 0, 0, $self->begin;
39 0           return $self;
40             }
41              
42             sub _step {
43             my ($self, $id) = (shift, shift);
44            
45             push @{ $self->{args}[$id] }, [@_];
46             return if $self->{fail} || --$self->{pending} || $self->{lock};
47              
48             local $self->{lock} = 1;
49             my @args = map {@$_} @{delete $self->{args}};
50             $self->{_ae_counter} = 0;
51             if (my $cb = shift @{$self->{steps} ||= []}) {
52             eval { $self->$cb(@args); 1 } or return $self->on_error->($@) and $self->{fail}++;
53             }
54              
55             if (! $self->{_ae_counter}) {
56             return $self->on_finish->( @args );
57             }
58              
59             if (! $self->{pending}) {
60             $self->{timers}{$id} = EV::timer 0, 0, $self->begin
61             }
62             }
63              
64             1;
65              
66             =encoding utf8
67              
68             =head1 NAME
69              
70             AnyEvent::Delay - Manage AnyEvent callbacks and control the flow of events
71              
72             =head1 SYNOPSIS
73              
74             # Synchronize multiple events
75             my $cv = AE::cv;
76             my $delay = AnyEvent::Delay->new();
77             $delay->on_finish(sub { say 'BOOM!'; $cv->send });
78             for my $i (1 .. 10) {
79             my $end = $delay->begin;
80             Mojo::IOLoop->timer($i => sub {
81             say 10 - $i;
82             $end->();
83             });
84             }
85             $cv->recv;
86              
87             # Sequentialize multiple events
88             my $cv = AE::cv;
89             my $delay = AnyEvent::Delay->new();
90             $delay->steps(
91            
92             # First step (parallel events)
93             sub {
94             my $delay = shift;
95             Mojo::IOLoop->timer(2 => $delay->begin);
96             http_get( 'http://www.yinyuetai.com' => $delay->begin );
97             say 'Second step in 2 seconds.';
98             },
99            
100             # Second step (parallel timers)
101             sub {
102             my ($delay, @args) = @_;
103             say "This http response is $args[1]->[1]{Status}";
104             Mojo::IOLoop->timer(1 => $delay->begin);
105             Mojo::IOLoop->timer(3 => $delay->begin);
106             say 'Third step in 3 seconds.';
107             },
108            
109             # Third step (the end)
110             sub {
111             my ($delay, @args) = @_;
112             say 'And done after 5 seconds total.';
113             $cv->send;
114             }
115             );
116             $cv->recv;
117              
118             =head1 DESCRIPTION
119              
120             L manages callbacks and controls the flow of events for L. This module is L version of AnyEvent.
121              
122             =head1 EVENTS
123              
124             L have method the following.
125              
126             =head2 on_error
127              
128             $delay->on_error(sub {
129             my ($delay, $err) = @_;
130             ...
131             });
132              
133             if an error occurs in one of the steps, breaking the chain.
134              
135             =head2 on_finish
136              
137             $delay->on_finish(sub {
138             my ($delay, @args) = @_;
139             ...
140             });
141              
142             the active event _ae_counter reaches zero and there are no more steps.
143              
144             =head1 METHODS
145              
146             =head2 begin
147              
148             my $without_first_arg_arrayref = $delay->begin;
149             my $with_first_arg_arrayref = $delay->begin(0);
150              
151             Increment active event _ae_counter, the returned callback can be used to decrement
152             the active event _ae_counter again. Arguments passed to the callback are queued in
153             the right order for the next step or C event method, the argument will be
154             array references for each begin callback.
155              
156              
157             =head2 steps
158              
159             $delay = $delay->steps(sub {...}, sub {...});
160              
161             Sequentialize multiple events, the first callback will run right away, and the
162             next one once the active event _ae_counter reaches zero. This chain will continue
163             until there are no more callbacks, a callback does not increment the active
164             event _ae_counter or an error occurs in a callback.
165              
166             =head1 SEE ALSO
167              
168             L.
169              
170             =cut