Skip to content

Instantly share code, notes, and snippets.

@daoswald
Last active April 9, 2018 05:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save daoswald/17c1c37de52c700d794dc867cae9ca49 to your computer and use it in GitHub Desktop.
Save daoswald/17c1c37de52c700d794dc867cae9ca49 to your computer and use it in GitHub Desktop.
Mojo::IOLoop::subprocess along with promises to allow for ->wait, and accumulation.
#!/usr/bin/env perl
use Mojolicious::Lite;
use Benchmark qw(:hireswallclock);
# The point: No controller logic in add1, mult2, power.
# But we will run add1 and mult2 in parallel, and then wait for them to finish before taking the power.
sub add1 { my $a = shift; sleep 2; return $a+1; }
sub mult2 { my $b = shift; sleep 2; return $b*2; }
sub power { my ($x, $y) = @_; sleep 1; return $x ** $y; }
any '/' => sub {
my ( $self ) = @_;
$self->render_later;
my $n = int(rand(5));
my $t0 = Benchmark->new;
my @promise;
foreach my $code (\&add1, \&mult2) {
my $prom = Mojo::Promise->new;
Mojo::IOLoop->subprocess(
sub {
return $code->($n);
},
sub {
my ($subprocess, $err, @res) = @_;
return $prom->reject($err) if $err;
$prom->resolve(@res);
},
);
push @promise, $prom;
}
Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
my $z_promise = Mojo::Promise->all(@promise)
->then(
sub {
my ($x, $y) = map {$_->[0]} @_;
return power($x, $y);
},
);
Mojo::Promise->all(@promise, $z_promise)
->then(
sub {
my ($x, $y, $z) = map {$_->[0]} @_;
my $t = timediff(Benchmark->new(), $t0)->real;
$self->render(text => "n=$n, x=$x, y=$y, z=$z;\nT=$t elapsed seconds\n");
}
)->wait;
};
app->start;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment