File: Delay.pm

package info (click to toggle)
libmojolicious-perl 2.98%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 2,968 kB
  • sloc: perl: 10,178; sh: 48; makefile: 8
file content (123 lines) | stat: -rw-r--r-- 2,590 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package Mojo::IOLoop::Delay;
use Mojo::Base 'Mojo::EventEmitter';

use Mojo::IOLoop;

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

# "Ah, alcohol and night-swimming. It's a winning combination."
sub begin {
  my $self = shift;
  $self->{counter}++;
  return sub { shift; $self->end(@_) };
}

sub end {
  my $self = shift;
  push @{$self->{args} ||= []}, @_;
  $self->emit_safe('finish', @{$self->{args}}) if --$self->{counter} <= 0;
}

# "Mrs. Simpson, bathroom is not for customers.
#  Please use the crack house across the street."
sub wait {
  my $self = shift;
  $self->once(finish => sub { shift->ioloop->stop });
  $self->ioloop->start;
  return wantarray ? @{$self->{args}} : $self->{args}[0];
}

1;

=head1 NAME

Mojo::IOLoop::Delay - Synchronize events

=head1 SYNOPSIS

  use Mojo::IOLoop::Delay;

  # Synchronize multiple events
  my $delay = Mojo::IOLoop::Delay->new;
  $delay->on(finish => sub { say 'BOOM!' });
  for my $i (1 .. 10) {
    $delay->begin;
    Mojo::IOLoop->timer($i => sub {
      say 10 - $i;
      $delay->end;
    });
  }

  # Wait for events if necessary
  $delay->wait unless Mojo::IOLoop->is_running;

=head1 DESCRIPTION

L<Mojo::IOLoop::Delay> synchronizes events for L<Mojo::IOLoop>.

=head1 EVENTS

L<Mojo::IOLoop::Delay> can emit the following events.

=head2 C<finish>

  $delay->on(finish => sub {
    my $delay = shift;
    ...
  });

Emitted safely once the active event counter reaches zero.

=head1 ATTRIBUTES

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

=head2 C<ioloop>

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

Loop object to control, defaults to the global L<Mojo::IOLoop> singleton.

=head1 METHODS

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

=head2 C<begin>

  my $cb = $delay->begin;

Increment active event counter, the returned callback can be used instead of
C<end>.

  my $delay = Mojo::IOLoop->delay;
  Mojo::UserAgent->new->get('mojolicio.us' => $delay->begin);
  my $tx = $delay->wait;

=head2 C<end>

  $delay->end;
  $delay->end(@args);

Decrement active event counter.

=head2 C<wait>

  my @args = $delay->wait;

Start C<ioloop> and stop it again once the C<finish> event gets emitted, only
works when C<ioloop> is not running already.

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

=head1 SEE ALSO

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

=cut