Newer Older
193 lines | 4.664kb
copy gitweblite soruce code
root authored on 2012-11-23
1
package Mojo::IOLoop::Delay;
2
use Mojo::Base 'Mojo::EventEmitter';
3

            
4
use Mojo::IOLoop;
5

            
6
has ioloop => sub { Mojo::IOLoop->singleton };
7

            
8
sub begin {
update Mojolicious 4.07
Yuki Kimoto authored on 2013-06-03
9
  my ($self, $ignore) = @_;
10
  $self->{pending}++;
11
  my $id = $self->{counter}++;
12
  return sub { (defined $ignore ? $ignore : 1) and shift; $self->_step($id, @_) };
copy gitweblite soruce code
root authored on 2012-11-23
13
}
14

            
upgraded Mojolicious to v3.7...
Yuki Kimoto authored on 2013-01-28
15
sub steps {
copy gitweblite soruce code
root authored on 2012-11-23
16
  my $self = shift;
upgraded Mojolicious to v3.7...
Yuki Kimoto authored on 2013-01-28
17
  $self->{steps} = [@_];
update Mojolicious to 4.57
Yuki Kimoto authored on 2013-12-02
18
  $self->ioloop->timer(0 => $self->begin);
upgraded Mojolicious to v3.7...
Yuki Kimoto authored on 2013-01-28
19
  return $self;
copy gitweblite soruce code
root authored on 2012-11-23
20
}
21

            
22
sub wait {
23
  my $self = shift;
update Mojolicious to 4.57
Yuki Kimoto authored on 2013-12-02
24

            
upgraded Mojolicious to v3.7...
Yuki Kimoto authored on 2013-01-28
25
  my @args;
update Mojolicious to 4.57
Yuki Kimoto authored on 2013-12-02
26
  $self->once(error => \&_die);
upgraded Mojolicious to v3.7...
Yuki Kimoto authored on 2013-01-28
27
  $self->once(finish => sub { shift->ioloop->stop; @args = @_ });
copy gitweblite soruce code
root authored on 2012-11-23
28
  $self->ioloop->start;
update Mojolicious to 4.57
Yuki Kimoto authored on 2013-12-02
29

            
upgraded Mojolicious to v3.7...
Yuki Kimoto authored on 2013-01-28
30
  return wantarray ? @args : $args[0];
31
}
32

            
update Mojolicious to 4.57
Yuki Kimoto authored on 2013-12-02
33
sub _die { $_[0]->has_subscribers('error') ? $_[0]->ioloop->stop : die $_[1] }
34

            
upgraded Mojolicious to v3.7...
Yuki Kimoto authored on 2013-01-28
35
sub _step {
36
  my ($self, $id) = (shift, shift);
37

            
update Mojolicious 4.07
Yuki Kimoto authored on 2013-06-03
38
  $self->{args}[$id] = [@_];
update Mojolicious to 4.57
Yuki Kimoto authored on 2013-12-02
39
  return if $self->{fail} || --$self->{pending} || $self->{lock};
update Mojolicious 4.07
Yuki Kimoto authored on 2013-06-03
40
  local $self->{lock} = 1;
41
  my @args = map {@$_} @{delete $self->{args}};
upgraded Mojolicious to v3.7...
Yuki Kimoto authored on 2013-01-28
42

            
update Mojolicious 4.07
Yuki Kimoto authored on 2013-06-03
43
  $self->{counter} = 0;
update Mojolicious to 4.57
Yuki Kimoto authored on 2013-12-02
44
  if (my $cb = shift @{$self->{steps} ||= []}) {
45
    eval { $self->$cb(@args); 1 } or return $self->emit(error => $@)->{fail}++;
46
  }
upgraded Mojolicious to v3.7...
Yuki Kimoto authored on 2013-01-28
47

            
update Mojolicious to 4.57
Yuki Kimoto authored on 2013-12-02
48
  return $self->emit(finish => @args) unless $self->{counter};
49
  $self->ioloop->timer(0 => $self->begin) unless $self->{pending};
copy gitweblite soruce code
root authored on 2012-11-23
50
}
51

            
52
1;
53

            
update Mojolicious to 4.57
Yuki Kimoto authored on 2013-12-02
54
=encoding utf8
55

            
copy gitweblite soruce code
root authored on 2012-11-23
56
=head1 NAME
57

            
update Mojolicious 4.07
Yuki Kimoto authored on 2013-06-03
58
Mojo::IOLoop::Delay - Manage callbacks and control the flow of events
copy gitweblite soruce code
root authored on 2012-11-23
59

            
60
=head1 SYNOPSIS
61

            
62
  use Mojo::IOLoop::Delay;
63

            
64
  # Synchronize multiple events
65
  my $delay = Mojo::IOLoop::Delay->new;
66
  $delay->on(finish => sub { say 'BOOM!' });
67
  for my $i (1 .. 10) {
update Mojolicious 4.07
Yuki Kimoto authored on 2013-06-03
68
    my $end = $delay->begin;
copy gitweblite soruce code
root authored on 2012-11-23
69
    Mojo::IOLoop->timer($i => sub {
70
      say 10 - $i;
update Mojolicious 4.07
Yuki Kimoto authored on 2013-06-03
71
      $end->();
copy gitweblite soruce code
root authored on 2012-11-23
72
    });
73
  }
update Mojolicious to 4.57
Yuki Kimoto authored on 2013-12-02
74
  $delay->wait unless Mojo::IOLoop->is_running;
copy gitweblite soruce code
root authored on 2012-11-23
75

            
upgraded Mojolicious to v3.7...
Yuki Kimoto authored on 2013-01-28
76
  # Sequentialize multiple events
77
  my $delay = Mojo::IOLoop::Delay->new;
78
  $delay->steps(
79

            
80
    # First step (simple timer)
81
    sub {
82
      my $delay = shift;
83
      Mojo::IOLoop->timer(2 => $delay->begin);
84
      say 'Second step in 2 seconds.';
85
    },
86

            
87
    # Second step (parallel timers)
88
    sub {
89
      my ($delay, @args) = @_;
90
      Mojo::IOLoop->timer(1 => $delay->begin);
91
      Mojo::IOLoop->timer(3 => $delay->begin);
92
      say 'Third step in 3 seconds.';
93
    },
94

            
95
    # Third step (the end)
96
    sub {
97
      my ($delay, @args) = @_;
98
      say 'And done after 5 seconds total.';
99
    }
100
  );
copy gitweblite soruce code
root authored on 2012-11-23
101
  $delay->wait unless Mojo::IOLoop->is_running;
102

            
103
=head1 DESCRIPTION
104

            
update Mojolicious 4.07
Yuki Kimoto authored on 2013-06-03
105
L<Mojo::IOLoop::Delay> manages callbacks and controls the flow of events for
106
L<Mojo::IOLoop>.
copy gitweblite soruce code
root authored on 2012-11-23
107

            
108
=head1 EVENTS
109

            
update Mojolicious and added...
Yuki Kimoto authored on 2013-03-20
110
L<Mojo::IOLoop::Delay> inherits all events from L<Mojo::EventEmitter> and can
111
emit the following new ones.
copy gitweblite soruce code
root authored on 2012-11-23
112

            
update Mojolicious to 4.57
Yuki Kimoto authored on 2013-12-02
113
=head2 error
114

            
115
  $delay->on(error => sub {
116
    my ($delay, $err) = @_;
117
    ...
118
  });
119

            
120
Emitted if an error occurs in one of the steps, breaking the chain, fatal if
121
unhandled.
122

            
update Mojolicious and added...
Yuki Kimoto authored on 2013-03-20
123
=head2 finish
copy gitweblite soruce code
root authored on 2012-11-23
124

            
125
  $delay->on(finish => sub {
upgraded Mojolicious to v3.7...
Yuki Kimoto authored on 2013-01-28
126
    my ($delay, @args) = @_;
copy gitweblite soruce code
root authored on 2012-11-23
127
    ...
128
  });
129

            
upgraded Mojolicious to v3.7...
Yuki Kimoto authored on 2013-01-28
130
Emitted once the active event counter reaches zero and there are no more
131
steps.
copy gitweblite soruce code
root authored on 2012-11-23
132

            
133
=head1 ATTRIBUTES
134

            
135
L<Mojo::IOLoop::Delay> implements the following attributes.
136

            
update Mojolicious and added...
Yuki Kimoto authored on 2013-03-20
137
=head2 ioloop
copy gitweblite soruce code
root authored on 2012-11-23
138

            
139
  my $ioloop = $delay->ioloop;
140
  $delay     = $delay->ioloop(Mojo::IOLoop->new);
141

            
upgraded Mojolicious to v3.7...
Yuki Kimoto authored on 2013-01-28
142
Event loop object to control, defaults to the global L<Mojo::IOLoop>
143
singleton.
copy gitweblite soruce code
root authored on 2012-11-23
144

            
145
=head1 METHODS
146

            
147
L<Mojo::IOLoop::Delay> inherits all methods from L<Mojo::EventEmitter> and
148
implements the following new ones.
149

            
update Mojolicious and added...
Yuki Kimoto authored on 2013-03-20
150
=head2 begin
copy gitweblite soruce code
root authored on 2012-11-23
151

            
update Mojolicious to 4.57
Yuki Kimoto authored on 2013-12-02
152
  my $without_first_arg = $delay->begin;
153
  my $with_first_arg    = $delay->begin(0);
copy gitweblite soruce code
root authored on 2012-11-23
154

            
update Mojolicious 4.07
Yuki Kimoto authored on 2013-06-03
155
Increment active event counter, the returned callback can be used to decrement
156
the active event counter again. Arguments passed to the callback are queued in
update Mojolicious to 4.57
Yuki Kimoto authored on 2013-12-02
157
the right order for the next step or L</"finish"> event and L</"wait"> method,
158
the first argument will be ignored by default.
copy gitweblite soruce code
root authored on 2012-11-23
159

            
update Mojolicious 4.07
Yuki Kimoto authored on 2013-06-03
160
  # Capture all arguments
copy gitweblite soruce code
root authored on 2012-11-23
161
  my $delay = Mojo::IOLoop->delay;
update Mojolicious 4.07
Yuki Kimoto authored on 2013-06-03
162
  Mojo::IOLoop->client({port => 3000} => $delay->begin(0));
163
  my ($loop, $err, $stream) = $delay->wait;
upgraded Mojolicious to v3.7...
Yuki Kimoto authored on 2013-01-28
164

            
update Mojolicious and added...
Yuki Kimoto authored on 2013-03-20
165
=head2 steps
upgraded Mojolicious to v3.7...
Yuki Kimoto authored on 2013-01-28
166

            
167
  $delay = $delay->steps(sub {...}, sub {...});
copy gitweblite soruce code
root authored on 2012-11-23
168

            
upgraded Mojolicious to v3.7...
Yuki Kimoto authored on 2013-01-28
169
Sequentialize multiple events, the first callback will run right away, and the
update Mojolicious to 4.57
Yuki Kimoto authored on 2013-12-02
170
next one once the active event counter reaches zero. This chain will continue
171
until there are no more callbacks, a callback does not increment the active
172
event counter or an error occurs in a callback.
copy gitweblite soruce code
root authored on 2012-11-23
173

            
update Mojolicious and added...
Yuki Kimoto authored on 2013-03-20
174
=head2 wait
copy gitweblite soruce code
root authored on 2012-11-23
175

            
update Mojolicious to 4.57
Yuki Kimoto authored on 2013-12-02
176
  my $arg  = $delay->wait;
copy gitweblite soruce code
root authored on 2012-11-23
177
  my @args = $delay->wait;
178

            
update Mojolicious to 4.57
Yuki Kimoto authored on 2013-12-02
179
Start L</"ioloop"> and stop it again once an L</"error"> or L</"finish"> event
180
gets emitted, only works when L</"ioloop"> is not running already.
copy gitweblite soruce code
root authored on 2012-11-23
181

            
182
  # Use the "finish" event to synchronize portably
183
  $delay->on(finish => sub {
184
    my ($delay, @args) = @_;
185
    ...
186
  });
187
  $delay->wait unless $delay->ioloop->is_running;
188

            
189
=head1 SEE ALSO
190

            
191
L<Mojolicious>, L<Mojolicious::Guides>, L<http://mojolicio.us>.
192

            
193
=cut