Skip to content

Instantly share code, notes, and snippets.

@Logioniz
Created December 5, 2015 23:21
Show Gist options
  • Save Logioniz/a46b4b6420254398712b to your computer and use it in GitHub Desktop.
Save Logioniz/a46b4b6420254398712b to your computer and use it in GitHub Desktop.
Example how handle long blocking operation when server asynchronous
#!/usr/bin/perl
use strict;
use warnings;
use v5.10;
use Mojolicious::Lite;
use Mojo::IOLoop;
use Mojo::IOLoop::ReadWriteFork;
plugin 'Mojolicious::Plugin::ForkCall';
get '/' => sub {
my $c = shift;
$c->render(template => 'index');
};
websocket '/ws' => sub {
my $c = shift;
$c->inactivity_timeout(60 * 10);
$c->on(message => sub {
my ($c, $msg) = @_;
if ($msg eq 'long_operation_1') {
$c->fork_call(
sub {
my @args = @_;
sleep 3;
return join ', ', @args;
},
['argument_1', 'argument_2' , 'argument_n'],
sub {
my ($c, @return) = @_;
$c->send($return[0]);
}
);
}
if ($msg eq 'long_operation_2') {
$c->stash(fork => my $fork = Mojo::IOLoop::ReadWriteFork->new);
my $cat_result = '';
$fork->on(error => sub {
my($fork, $error) = @_;
warn $error;
});
$fork->on(close => sub {
my($fork, $exit_value, $signal) = @_;
$c->send($cat_result);
delete $c->stash->{fork};
});
$fork->on(read => sub {
my ($fork, $buffer) = @_; # $buffer = both STDERR and STDOUT
$cat_result .= $buffer;
});
$fork->start(
program => 'ls',
program_args => ['-la'],
);
}
});
$c->on(finish => sub {
my ($c, $code, $reason) = @_;
});
} => 'ws';
app->start;
__DATA__
@@ index.html.ep
<head>
<script src="http://code.jquery.com/jquery-2.1.3.min.js"></script>
</head>
<body>
<script>
$(document).ready(function () {
function websocket () {
var ws = new WebSocket('<%= url_for('ws')->to_abs %>');
ws.onmessage = function(event) {
document.body.innerHTML += event.data + '<br/>';
};
ws.onopen = function() {
ws.send('long_operation_2');
}
}
websocket();
});
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment