Skip to content

Commit

Permalink
merged Mojo::IOLoop::Steps and Mojo::IOLoop::Delay
Browse files Browse the repository at this point in the history
  • Loading branch information
kraih committed Aug 17, 2012
1 parent 138cb00 commit 6212486
Show file tree
Hide file tree
Showing 9 changed files with 158 additions and 215 deletions.
4 changes: 2 additions & 2 deletions Changes
@@ -1,7 +1,7 @@

3.32 2012-08-17
- Added Mojo::IOLoop::Steps. (judofyr, marcus, sri)
- Added steps method to Mojo::IOLoop.
- Added event sequentialization support to Mojo::IOLoop::Delay.
(judofyr, marcus, sri)
- Added tap method to Mojo::Base.
- Improved documentation.
- Fixed json_has method in Test::Mojo.
Expand Down
3 changes: 2 additions & 1 deletion lib/Mojo/Base.pm
Expand Up @@ -220,7 +220,8 @@ accessor read time if there's no set value.
$object = $object->tap(sub {...});
Tap into a method chain to perform operations on an object within the chain.
K combinator, tap into a method chain to perform operations on an object
within the chain.
=head1 DEBUGGING
Expand Down
64 changes: 28 additions & 36 deletions lib/Mojo/IOLoop.pm
Expand Up @@ -5,7 +5,6 @@ use Carp 'croak';
use Mojo::IOLoop::Client;
use Mojo::IOLoop::Delay;
use Mojo::IOLoop::Server;
use Mojo::IOLoop::Steps;
use Mojo::IOLoop::Stream;
use Mojo::Reactor::Poll;
use Mojo::Util 'md5_sum';
Expand Down Expand Up @@ -71,12 +70,12 @@ sub client {
}

sub delay {
my ($self, $cb) = @_;
my $self = shift;
$self = $self->singleton unless ref $self;

my $delay = Mojo::IOLoop::Delay->new;
weaken $delay->ioloop($self)->{ioloop};
$delay->once(finish => $cb) if $cb;
@_ > 1 ? $delay->steps(@_) : $delay->once(finish => shift) if @_;

return $delay;
}
Expand Down Expand Up @@ -157,8 +156,6 @@ sub start {
(ref $self ? $self : $self->singleton)->reactor->start;
}

sub steps { shift; Mojo::IOLoop::Steps->new(@_) }

sub stop {
my $self = shift;
(ref $self ? $self : $self->singleton)->reactor->stop;
Expand Down Expand Up @@ -446,9 +443,11 @@ L<Mojo::IOLoop::Client/"connect">.
my $delay = Mojo::IOLoop->delay;
my $delay = $loop->delay;
my $delay = $loop->delay(sub {...});
my $delay = $loop->delay(sub {...}, sub {...});
Get L<Mojo::IOLoop::Delay> object to synchronize events and subscribe to event
L<Mojo::IOLoop::Delay/"finish"> if optional callback is provided.
Get L<Mojo::IOLoop::Delay> object to control the flow of events. A single
callback will be treated as a subscriber to the C<finish> event, and multiple
ones as a chain of steps.
# Synchronize multiple events
my $delay = Mojo::IOLoop->delay(sub { say 'BOOM!' });
Expand All @@ -460,6 +459,28 @@ L<Mojo::IOLoop::Delay/"finish"> if optional callback is provided.
});
}
# Sequentialize multiple events
my $delay = Mojo::IOLoop->delay(
# First step (simple timer)
sub {
my $delay = shift;
Mojo::IOLoop->timer(2 => $delay->next);
say 'Second step in 2 seconds.';
},
# Second step (parallel timers)
sub {
my $delay = shift;
Mojo::IOLoop->timer(1 => $delay->next);
Mojo::IOLoop->timer(3 => $delay->next);
say 'Third step in 3 seconds.';
},
# Third step (the end)
sub { say 'And done after 5 seconds total.' }
);
# Wait for events if necessary
$delay->wait unless Mojo::IOLoop->is_running;
Expand Down Expand Up @@ -543,35 +564,6 @@ reactors stop automatically if there are no events being watched anymore.
# Start event loop only if it is not running already
Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
=head2 C<steps>
my $steps = Mojo::IOLoop->steps(sub {...}, sub {...});
my $steps = $loop->steps(sub {...}, sub {...});
Get L<Mojo::IOLoop::Steps> object to sequentialize events.
# Sequentialize multiple events
Mojo::IOLoop->steps(
# First step (simple timer)
sub {
my $steps = shift;
Mojo::IOLoop->timer(2 => $steps->next);
say 'Second step in 2 seconds.';
},
# Second step (parallel timers)
sub {
my $steps = shift;
Mojo::IOLoop->timer(1 => $steps->next);
Mojo::IOLoop->timer(3 => $steps->next);
say 'Third step in 3 seconds.';
},
# Third step (the end)
sub { say 'And done after 5 seconds total.' }
);
=head2 C<stop>
Mojo::IOLoop->stop;
Expand Down
86 changes: 72 additions & 14 deletions lib/Mojo/IOLoop/Delay.pm
Expand Up @@ -8,31 +8,53 @@ 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(@_) };
my $id = $self->{counter}++;
return sub { shift; $self->_step($id, @_) };
}

sub end {
sub end { shift->_step(undef, @_) }

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

# "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 });
my @args;
$self->once(finish => sub { shift->ioloop->stop; @args = @_ });
$self->ioloop->start;
return wantarray ? @{$self->{args}} : $self->{args}[0];
return wantarray ? @args : $args[0];
}

sub _step {
my ($self, $id) = (shift, shift);

my $ordered = $self->{ordered} ||= [];
my $unordered = $self->{unordered} ||= [];
if (defined $id) { $ordered->[$id] = [@_] }
else { push @$unordered, @_ }

return $self->{counter} unless --$self->{counter} <= 0;

my $cb = shift @{$self->{steps} ||= []};
$self->{$_} = [] for qw(ordered unordered);
my @ordered = map {@$_} grep {defined} @$ordered;
$self->$cb(@ordered, @$unordered) if $cb;
$self->emit('finish', @ordered, @$unordered) unless @{$self->{steps}};

return 0;
}

1;

=head1 NAME
Mojo::IOLoop::Delay - Synchronize events
Mojo::IOLoop::Delay - Control the flow of events
=head1 SYNOPSIS
Expand All @@ -49,12 +71,38 @@ Mojo::IOLoop::Delay - Synchronize events
});
}
# Sequentialize multiple events
my $delay = Mojo::IOLoop::Delay->new;
$delay->steps(
# First step (simple timer)
sub {
my $delay = shift;
Mojo::IOLoop->timer(2 => $delay->next);
say 'Second step in 2 seconds.';
},
# Second step (parallel timers)
sub {
my ($delay, @args) = @_;
Mojo::IOLoop->timer(1 => $delay->next);
Mojo::IOLoop->timer(3 => $delay->next);
say 'Third step in 3 seconds.';
},
# Third step (the end)
sub {
my ($delay, @args) = @_;
say 'And done after 5 seconds total.';
}
);
# Wait for events if necessary
$delay->wait unless Mojo::IOLoop->is_running;
=head1 DESCRIPTION
L<Mojo::IOLoop::Delay> synchronizes events for L<Mojo::IOLoop>.
L<Mojo::IOLoop::Delay> controls the flow of events for L<Mojo::IOLoop>.
=head1 EVENTS
Expand All @@ -67,7 +115,8 @@ L<Mojo::IOLoop::Delay> can emit the following events.
...
});
Emitted safely once the active event counter reaches zero.
Emitted once the active event counter reaches zero and there are no more
steps.
=head1 ATTRIBUTES
Expand All @@ -91,7 +140,8 @@ implements the following new ones.
my $cb = $delay->begin;
Increment active event counter, the returned callback can be used instead of
C<end>. Note that the first argument passed to the callback will be ignored.
C<end>, which has the advantage of preserving the order of arguments. Note
that the first argument passed to the callback will be ignored.
my $delay = Mojo::IOLoop->delay;
Mojo::UserAgent->new->get('mojolicio.us' => $delay->begin);
Expand All @@ -102,8 +152,16 @@ C<end>. Note that the first argument passed to the callback will be ignored.
my $remaining = $delay->end;
my $remaining = $delay->end(@args);
Decrement active event counter, all arguments are queued for the C<finish>
event and C<wait> method.
Decrement active event counter, all arguments are queued for the next step or
C<finish> event and C<wait> method.
=head2 C<steps>
$delay = $delay->steps(sub {...}, sub {...});
Sequentialize multiple events, the first callback will run right away, and the
next one once the active event counter reaches zero, this chain will continue
until there are no more callbacks left.
=head2 C<wait>
Expand Down
95 changes: 0 additions & 95 deletions lib/Mojo/IOLoop/Steps.pm

This file was deleted.

1 change: 1 addition & 0 deletions lib/Mojolicious/Renderer.pm
Expand Up @@ -58,6 +58,7 @@ sub get_data_template {
return $loader->data($self->{index}{$template}, $template);
}

# "My god, it's full of geezers."
sub render {
my ($self, $c, $args) = @_;
$args ||= {};
Expand Down
1 change: 1 addition & 0 deletions lib/Mojolicious/Static.pm
Expand Up @@ -51,6 +51,7 @@ sub file {
return $self->_get_file(catfile($PUBLIC, split('/', $rel)));
}

# "It's not just safe, it's 40% safe!"
sub serve {
my ($self, $c, $rel) = @_;
return unless my $asset = $self->file($rel);
Expand Down

0 comments on commit 6212486

Please sign in to comment.