spawn subprocess with promise

This commit is contained in:
Denis Fedoseev 2018-08-01 10:11:43 +03:00
parent a774698d6e
commit 87ad4111a8

View file

@ -4,6 +4,8 @@ use warnings;
use lib 'lib'; use lib 'lib';
use Mojolicious::Lite; # app, get, post is exported. use Mojolicious::Lite; # app, get, post is exported.
use Mojo::Promise;
use Mojo::IOLoop;
use File::Basename qw/basename fileparse/; use File::Basename qw/basename fileparse/;
use File::Path 'mkpath'; use File::Path 'mkpath';
@ -255,34 +257,48 @@ post '/upload' => ( authenticated => 1 ) => sub {
# Save to file # Save to file
$image->move_to($image_file); $image->move_to($image_file);
# Operation that would block the event loop for 5 seconds $log->debug("Spwan subprocess");
my $subprocess = Mojo::IOLoop::Subprocess->new;
$subprocess->run(
sub {
my $subprocess = shift;
store_image($image_file, $image->filename, $user_id);
},
sub {
my ($subprocess, $err, @results) = @_;
say "Subprocess error: $err" and return if $err;
say "I $results[0] $results[1]!";
}
);
$subprocess->ioloop->start unless $subprocess->ioloop->is_running; my $promise = store_image($image_file, $image->filename, $user_id);
$self->render(
json => { Mojo::Promise->all($promise)->then(sub {
files => [ $self->render(
{ json => {
name => $image->filename, files => [
size => $image->size, {
url => sprintf( '/images/orig/%s', $filename ), name => $image->filename,
thumbnailUrl => sprintf( '/images/200/%s', $filename ), size => $image->size,
url => sprintf( '/images/orig/%s', $filename ),
thumbnailUrl => sprintf( '/images/200/%s', $filename ),
}
]
} }
] );
} })->wait;
);
# $log->debug("wait for promise");
# Mojo::Promise->all($spawn_subprocess)->then(sub {
# $self->render(
# json => {
# files => [
# {
# name => $image->filename,
# size => $image->size,
# url => sprintf( '/images/orig/%s', $filename ),
# thumbnailUrl => sprintf( '/images/200/%s', $filename ),
# }
# ]
# }
# );
# })->catch(sub {
# my $err = shift;
# warn "Something went wrong: $err";
# })->wait;
# Redirect to top page # Redirect to top page
# $self->redirect_to('index'); # $self->redirect_to('index');
@ -310,47 +326,65 @@ sub store_image {
my $original_filename = shift; my $original_filename = shift;
my $user_id = shift; my $user_id = shift;
my $promise = Mojo::Promise->new;
# Operation that would block the event loop for 5 seconds
Mojo::IOLoop->subprocess(
sub {
my $subprocess = shift;
my $filename = fileparse($image_file); my $filename = fileparse($image_file);
my $imager = Imager->new(); my $imager = Imager->new();
$imager->read( file => $image_file ) or die $imager->errstr; $imager->read( file => $image_file ) or die $imager->errstr;
#http://sylvana.net/jpegcrop/exif_orientation.html #http://sylvana.net/jpegcrop/exif_orientation.html
#http://myjaphoo.de/docs/exifidentifiers.html #http://myjaphoo.de/docs/exifidentifiers.html
my $rotation_angle = $imager->tags( name => "exif_orientation" ) || 1; my $rotation_angle = $imager->tags( name => "exif_orientation" ) || 1;
$log->debug( $log->debug(
"Rotation angle [" . $rotation_angle . "]" ); "Rotation angle [" . $rotation_angle . "]" );
if ( $rotation_angle == 3 ) { if ( $rotation_angle == 3 ) {
$imager = $imager->rotate( degrees => 180 ); $imager = $imager->rotate( degrees => 180 );
} }
elsif ( $rotation_angle == 6 ) { elsif ( $rotation_angle == 6 ) {
$imager = $imager->rotate( degrees => 90 ); $imager = $imager->rotate( degrees => 90 );
} }
my $original_width = $imager->getwidth(); my $original_width = $imager->getwidth();
for my $scale (@scale_width) { for my $scale (@scale_width) {
#Skip sizes which more than original image #Skip sizes which more than original image
if ( $scale >= $original_width ) { if ( $scale >= $original_width ) {
next; next;
}
my $scaled = $imager->scale( xpixels => $scale );
$scaled->write( file =>
File::Spec->catfile( get_path( $user_id, $scale ), $filename ) )
or die $scaled->errstr;
}
if ( !$db->add_file( $user_id, $filename, $original_filename ) ) {
$log->error(sprintf('Can\'t save file %s', $filename));
die sprintf('Can\'t save file %s', $filename);
}
$log->debug("done!");
return $filename;
},
sub {
my ($subprocess, $err, @results) = @_;
say "Subprocess error: $err" and return if $err;
$promise->reject("I $results[0] $results[1]!") if $err;
$promise->resolve(@results);
} }
);
my $scaled = $imager->scale( xpixels => $scale ); return $promise;
$scaled->write( file =>
File::Spec->catfile( get_path( $user_id, $scale ), $filename ) )
or die $scaled->errstr;
}
if ( !$db->add_file( $user_id, $filename, $original_filename ) ) {
$log->error(sprintf('Can\'t save file %s', $filename));
die sprintf('Can\'t save file %s', $filename);
}
return $filename;
} }
Mojo::IOLoop->start;
app->start; app->start;