Skip to content

Commit

Permalink
added error event and also attach deserialize errors to it
Browse files Browse the repository at this point in the history
  • Loading branch information
jberger committed Jul 25, 2014
1 parent 76a2beb commit 1372b09
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 31 deletions.
34 changes: 27 additions & 7 deletions lib/Mojo/IOLoop/ForkCall.pm
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ has 'weaken' => 0;

sub run {
my ($self, @args) = @_;
$self->ioloop->delay(sub{ $self->_run(@args) });
my $delay = $self->ioloop->delay(sub{ $self->_run(@args) });
$delay->catch(sub{ $self->emit( error => $_[1] ) });
return $self;
}

Expand Down Expand Up @@ -79,15 +80,27 @@ sub _run {

Scalar::Util::weaken($self) if $self->weaken;

$stream->on( error => sub { $self->emit( error => $_[1] ) if $self } );

my $deserializer = $self->deserializer;
$stream->on( close => sub {
return unless $$ == $parent; # not my stream!
my $res = do {
local $@;
eval { $deserializer->($buffer) } || [$@];
};
$self->$cb(@$res) if $cb;
$self->emit( finish => @$res ) if $self;
local $@;

# attempt to deserialize, emit error and return early
my $res = eval { $deserializer->($buffer) };
if ($@) {
$self->emit( error => $@ ) if $self;
waitpid $child, 0;
return;
}

# call the callback, emit error if it fails
eval { $self->$cb(@$res) if $cb };
$self->emit( error => $@ ) if $@ and $self;

# emit the finish event, emit error if IT fails
$self->emit_safe( finish => @$res ) if $self;

waitpid $child, 0;
});
Expand Down Expand Up @@ -169,6 +182,13 @@ Still, use with caution, and no running with scissors!
This module inherits all events from L<Mojo::EventEmitter> and implements the following addtional ones.
=head2 error
$fc->on( error => sub { my ($fc, $err) = @_; } );
Emitted in the parent when the parent process encounters an error.
Fatal if not handled.
=head2 finish
$fc->on( finish => sub {
Expand Down
42 changes: 26 additions & 16 deletions t/bad_deserialize.t
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,32 @@ use Mojo::IOLoop::ForkCall;
use Test::More;

my $job = sub{'Lived'};
my ($err, $res);
my $fc = Mojo::IOLoop::ForkCall->new;
$fc->on(finish => sub { my $fc = shift; $err = shift; $res = shift; $fc->ioloop->stop });
$fc->run($job);
$fc->ioloop->start;

ok ! $err;
is $res, 'Lived';

$fc->deserializer(sub{ die "Died\n" });
$fc->run($job);
$fc->ioloop->start;

chomp $err;
is $err, 'Died';
ok ! $res;

{
my ($err, $res);
my $fc = Mojo::IOLoop::ForkCall->new;
$fc->on(error => sub { $err = $_[1] });
$fc->on(finish => sub { my $fc = shift; $err = shift; $res = shift; $fc->ioloop->stop });
$fc->run($job);
$fc->ioloop->start;

ok ! $err;
is $res, 'Lived';
}

{
my ($err, $res);
my $fc = Mojo::IOLoop::ForkCall->new;
$fc->on(error => sub { $err = $_[1] });
$fc->on(finish => sub { $res = $_[2] });
$fc->deserializer(sub{ die "Died\n" });
$fc->run($job);
$fc->ioloop->start;

chomp $err;
is $err, 'Died';
ok ! $res;
}

done_testing;

30 changes: 22 additions & 8 deletions t/basic.t
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,28 @@ Mojo::IOLoop->start;
ok $tick, 'main process not blocked';
is_deeply \@res, [ $fc, undef, $pid, ['test']], 'return value correct';

my $err;
$fc->run(
sub { die "Died!\n" },
sub { shift; $err = shift; Mojo::IOLoop->stop },
);
Mojo::IOLoop->start;
chomp $err;
is $err, 'Died!';
{
my $err;
$fc->run(
sub { die "Died!\n" },
sub { shift; $err = shift; Mojo::IOLoop->stop },
);
Mojo::IOLoop->start;
chomp $err;
is $err, 'Died!';
}

{
my $err;
$fc->on( error => sub { $err = $_[1]; Mojo::IOLoop->stop } );
$fc->run(
sub { return 1 },
sub { die "Argh\n" },
);
Mojo::IOLoop->start;
chomp $err;
is $err, 'Argh';
}

done_testing;

0 comments on commit 1372b09

Please sign in to comment.