Hello community, here is the log from the commit of package perl-Mojolicious for openSUSE:Factory checked in at 2016-09-05 21:18:13 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/perl-Mojolicious (Old) and /work/SRC/openSUSE:Factory/.perl-Mojolicious.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "perl-Mojolicious" Changes: -------- --- /work/SRC/openSUSE:Factory/perl-Mojolicious/perl-Mojolicious.changes 2016-08-22 10:49:21.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.perl-Mojolicious.new/perl-Mojolicious.changes 2016-09-05 21:18:16.000000000 +0200 @@ -1,0 +2,20 @@ +Wed Aug 31 05:58:50 UTC 2016 - [email protected] + +- updated to 7.05 + see /usr/share/doc/packages/perl-Mojolicious/Changes + + 7.05 2016-08-29 + - Fixed bug in Mojo::IOLoop::Subprocess where EV would steal the subprocess + exit status. + + 7.04 2016-08-28 + - Added EXPERIMENTAL support for performing computationally expensive + operations in subprocesses, without blocking the event loop. (jberger, sri) + - Added EXPERIMENTAL module Mojo::IOLoop::Subprocess. (jberger, sri) + - Added EXPERIMENTAL subprocess method to Mojo::IOLoop. (jberger, sri) + - Improved many methods in Mojolicious::Controller to die more gracefully if + the connection has already been closed. + - Fixed bug where Mojo::UserAgent would try to follow redirects for CONNECT + requests. + +------------------------------------------------------------------- Old: ---- Mojolicious-7.03.tar.gz New: ---- Mojolicious-7.05.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ perl-Mojolicious.spec ++++++ --- /var/tmp/diff_new_pack.lMxJpM/_old 2016-09-05 21:18:18.000000000 +0200 +++ /var/tmp/diff_new_pack.lMxJpM/_new 2016-09-05 21:18:18.000000000 +0200 @@ -17,7 +17,7 @@ Name: perl-Mojolicious -Version: 7.03 +Version: 7.05 Release: 0 %define cpan_name Mojolicious Summary: Real-time web framework ++++++ Mojolicious-7.03.tar.gz -> Mojolicious-7.05.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-7.03/Changes new/Mojolicious-7.05/Changes --- old/Mojolicious-7.03/Changes 2016-08-17 18:37:48.000000000 +0200 +++ new/Mojolicious-7.05/Changes 2016-08-29 17:10:48.000000000 +0200 @@ -1,4 +1,18 @@ +7.05 2016-08-29 + - Fixed bug in Mojo::IOLoop::Subprocess where EV would steal the subprocess + exit status. + +7.04 2016-08-28 + - Added EXPERIMENTAL support for performing computationally expensive + operations in subprocesses, without blocking the event loop. (jberger, sri) + - Added EXPERIMENTAL module Mojo::IOLoop::Subprocess. (jberger, sri) + - Added EXPERIMENTAL subprocess method to Mojo::IOLoop. (jberger, sri) + - Improved many methods in Mojolicious::Controller to die more gracefully if + the connection has already been closed. + - Fixed bug where Mojo::UserAgent would try to follow redirects for CONNECT + requests. + 7.03 2016-08-17 - Fixed packaging errors. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-7.03/MANIFEST new/Mojolicious-7.05/MANIFEST --- old/Mojolicious-7.03/MANIFEST 2016-08-17 18:39:29.000000000 +0200 +++ new/Mojolicious-7.05/MANIFEST 2016-08-29 18:43:03.000000000 +0200 @@ -37,6 +37,7 @@ lib/Mojo/IOLoop/resources/server.key lib/Mojo/IOLoop/Server.pm lib/Mojo/IOLoop/Stream.pm +lib/Mojo/IOLoop/Subprocess.pm lib/Mojo/JSON.pm lib/Mojo/JSON/Pointer.pm lib/Mojo/Loader.pm @@ -206,6 +207,7 @@ t/mojo/request.t t/mojo/request_cgi.t t/mojo/response.t +t/mojo/subprocess.t t/mojo/template.t t/mojo/templates/exception.mt t/mojo/templates/test.mt diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-7.03/META.json new/Mojolicious-7.05/META.json --- old/Mojolicious-7.03/META.json 2016-08-17 18:39:28.000000000 +0200 +++ new/Mojolicious-7.05/META.json 2016-08-29 18:43:03.000000000 +0200 @@ -4,7 +4,7 @@ "Sebastian Riedel <[email protected]>" ], "dynamic_config" : 0, - "generated_by" : "ExtUtils::MakeMaker version 7.22, CPAN::Meta::Converter version 2.150005", + "generated_by" : "ExtUtils::MakeMaker version 7.24, CPAN::Meta::Converter version 2.150010", "license" : [ "artistic_2" ], @@ -58,6 +58,6 @@ }, "x_IRC" : "irc://irc.perl.org/#mojo" }, - "version" : "7.03", + "version" : "7.05", "x_serialization_backend" : "JSON::PP version 2.27400" } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-7.03/META.yml new/Mojolicious-7.05/META.yml --- old/Mojolicious-7.03/META.yml 2016-08-17 18:39:28.000000000 +0200 +++ new/Mojolicious-7.05/META.yml 2016-08-29 18:43:03.000000000 +0200 @@ -7,7 +7,7 @@ configure_requires: ExtUtils::MakeMaker: '0' dynamic_config: 0 -generated_by: 'ExtUtils::MakeMaker version 7.22, CPAN::Meta::Converter version 2.150005' +generated_by: 'ExtUtils::MakeMaker version 7.24, CPAN::Meta::Converter version 2.150010' license: artistic_2 meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html @@ -31,5 +31,5 @@ homepage: http://mojolicious.org license: http://www.opensource.org/licenses/artistic-license-2.0 repository: https://github.com/kraih/mojo.git -version: '7.03' +version: '7.05' x_serialization_backend: 'CPAN::Meta::YAML version 0.018' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-7.03/lib/Mojo/IOLoop/Stream.pm new/Mojolicious-7.05/lib/Mojo/IOLoop/Stream.pm --- old/Mojolicious-7.03/lib/Mojo/IOLoop/Stream.pm 2016-07-19 02:38:18.000000000 +0200 +++ new/Mojolicious-7.05/lib/Mojo/IOLoop/Stream.pm 2016-08-27 04:52:25.000000000 +0200 @@ -8,8 +8,6 @@ has reactor => sub { Mojo::IOLoop->singleton->reactor }; -sub DESTROY { Mojo::Util::_global_destruction() or shift->close } - sub close { my $self = shift; return unless my $reactor = $self->reactor; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-7.03/lib/Mojo/IOLoop/Subprocess.pm new/Mojolicious-7.05/lib/Mojo/IOLoop/Subprocess.pm --- old/Mojolicious-7.03/lib/Mojo/IOLoop/Subprocess.pm 1970-01-01 01:00:00.000000000 +0100 +++ new/Mojolicious-7.05/lib/Mojo/IOLoop/Subprocess.pm 2016-08-29 17:32:08.000000000 +0200 @@ -0,0 +1,148 @@ +package Mojo::IOLoop::Subprocess; +use Mojo::Base -base; + +use Carp 'croak'; +use Config; +use Mojo::IOLoop; +use Mojo::IOLoop::Stream; +use POSIX (); +use Storable; + +has deserialize => sub { \&Storable::thaw }; +has ioloop => sub { Mojo::IOLoop->singleton }; +has serialize => sub { \&Storable::freeze }; + +sub pid { shift->{pid} } + +sub run { + my ($self, $child, $parent) = @_; + + # No fork emulation support + croak 'Subprocesses do not support fork emulation' if $Config{d_pseudofork}; + + # Pipe for subprocess communication + pipe(my $reader, my $writer) or croak "Can't create pipe: $!"; + $writer->autoflush(1); + + # Child + croak "Can't fork: $!" unless defined(my $pid = $self->{pid} = fork); + unless ($pid) { + $self->ioloop->reset; + my $results = eval { [$self->$child] } || []; + print $writer $self->serialize->([$@, @$results]); + POSIX::_exit(0); + } + + # Parent + my $stream = Mojo::IOLoop::Stream->new($reader); + $self->ioloop->stream($stream); + my $buffer = ''; + $stream->on(read => sub { $buffer .= pop }); + $stream->on( + close => sub { + waitpid $pid, 0; + my $results = eval { $self->deserialize->($buffer) } || []; + $self->$parent(shift(@$results) // $@, @$results); + } + ); + return $self; +} + +1; + +=encoding utf8 + +=head1 NAME + +Mojo::IOLoop::Subprocess - Subprocesses + +=head1 SYNOPSIS + + use Mojo::IOLoop::Subprocess; + + # Operation that would block the event loop for 5 seconds + my $subprocess = Mojo::IOLoop::Subprocess->new; + $subprocess->run( + sub { + my $subprocess = shift; + sleep 5; + return '♥', 'Mojolicious'; + }, + sub { + my ($subprocess, $err, @results) = @_; + say "I $results[0] $results[1]!"; + } + ); + + # Start event loop if necessary + $subprocess->ioloop->start unless $subprocess->ioloop->is_running; + +=head1 DESCRIPTION + +L<Mojo::IOLoop::Subprocess> allows L<Mojo::IOLoop> to perform computationally +expensive operations in subprocesses, without blocking the event loop. Note that +this module is EXPERIMENTAL and might change without warning! + +=head1 ATTRIBUTES + +L<Mojo::IOLoop::Subprocess> implements the following attributes. + +=head2 deserialize + + my $cb = $subprocess->deserialize; + $subprocess = $subprocess->deserialize(sub {...}); + +A callback used to deserialize subprocess return values, defaults to using +L<Storable>. + + $subprocess->deserialize(sub { + my $bytes = shift; + return []; + }); + +=head2 ioloop + + my $loop = $subprocess->ioloop; + $subprocess = $subprocess->ioloop(Mojo::IOLoop->new); + +Event loop object to control, defaults to the global L<Mojo::IOLoop> singleton. + +=head2 serialize + + my $cb = $subprocess->serialize; + $subprocess = $subprocess->serialize(sub {...}); + +A callback used to serialize subprocess return values, defaults to using +L<Storable>. + + $subprocess->serialize(sub { + my $array = shift; + return ''; + }); + +=head1 METHODS + +L<Mojo::IOLoop::Subprocess> inherits all methods from L<Mojo::Base> and +implements the following new ones. + +=head2 pid + + my $pid = $subprocess->pid; + +Process id of the spawned subprocess if available. + +=head2 run + + $subprocess = $subprocess->run(sub {...}, sub {...}); + +Execute the first callback in a child process and wait for it to return one or +more values, without blocking L</"ioloop"> in the parent process. Then execute +the second callback in the parent process with the results. The return values of +the first callback and exceptions thrown by it, will be serialized with +L<Storable>, so they can be shared between processes. + +=head1 SEE ALSO + +L<Mojolicious>, L<Mojolicious::Guides>, L<http://mojolicious.org>. + +=cut diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-7.03/lib/Mojo/IOLoop.pm new/Mojolicious-7.05/lib/Mojo/IOLoop.pm --- old/Mojolicious-7.03/lib/Mojo/IOLoop.pm 2016-07-19 02:38:18.000000000 +0200 +++ new/Mojolicious-7.05/lib/Mojo/IOLoop.pm 2016-08-27 14:46:02.000000000 +0200 @@ -8,6 +8,7 @@ use Mojo::IOLoop::Delay; use Mojo::IOLoop::Server; use Mojo::IOLoop::Stream; +use Mojo::IOLoop::Subprocess; use Mojo::Reactor::Poll; use Mojo::Util qw(md5_sum steady_time); use Scalar::Util qw(blessed weaken); @@ -145,6 +146,12 @@ return $c->{stream}; } +sub subprocess { + my $subprocess = Mojo::IOLoop::Subprocess->new; + weaken $subprocess->ioloop(_instance(shift))->{ioloop}; + return $subprocess->run(@_); +} + sub timer { shift->_timer(timer => @_) } sub _id { @@ -595,6 +602,29 @@ # Increase inactivity timeout for connection to 300 seconds Mojo::IOLoop->stream($id)->timeout(300); +=head2 subprocess + + my $subprocess = Mojo::IOLoop->subprocess(sub {...}, sub {...}); + my $subprocess = $loop->subprocess(sub {...}, sub {...}); + +Build L<Mojo::IOLoop::Subprocess> object to perform computationally expensive +operations in subprocesses, without blocking the event loop. Callbacks will be +passed along to L<Mojo::IOLoop::Subprocess/"run">. Note that this method is +EXPERIMENTAL and might change without warning! + + # Operation that would block the event loop for 5 seconds + Mojo::IOLoop->subprocess( + sub { + my $subprocess = shift; + sleep 5; + return '♥', 'Mojolicious'; + }, + sub { + my ($subprocess, $err, @results) = @_; + say "I $results[0] $results[1]!"; + } + ); + =head2 timer my $id = Mojo::IOLoop->timer(3 => sub {...}); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-7.03/lib/Mojo/Server/Daemon.pm new/Mojolicious-7.05/lib/Mojo/Server/Daemon.pm --- old/Mojolicious-7.03/lib/Mojo/Server/Daemon.pm 2016-08-05 16:07:06.000000000 +0200 +++ new/Mojolicious-7.05/lib/Mojo/Server/Daemon.pm 2016-08-27 04:08:11.000000000 +0200 @@ -21,9 +21,8 @@ sub DESTROY { return if Mojo::Util::_global_destruction(); my $self = shift; - $self->_remove($_) for keys %{$self->{connections} || {}}; my $loop = $self->ioloop; - $loop->remove($_) for @{$self->acceptors}; + $loop->remove($_) for keys %{$self->{connections} || {}}, @{$self->acceptors}; } sub run { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-7.03/lib/Mojo/Transaction/HTTP.pm new/Mojolicious-7.05/lib/Mojo/Transaction/HTTP.pm --- old/Mojolicious-7.03/lib/Mojo/Transaction/HTTP.pm 2016-07-19 02:38:18.000000000 +0200 +++ new/Mojolicious-7.05/lib/Mojo/Transaction/HTTP.pm 2016-08-26 22:02:30.000000000 +0200 @@ -93,16 +93,13 @@ # Switch to body if ($self->{write} <= 0) { - $self->{offset} = 0; + @$self{qw(http_state offset)} = ('body', 0); # Response without body if ($head && $self->is_empty) { $self->completed } # Body - else { - $self->{http_state} = 'body'; - $self->{write} = $msg->content->is_dynamic ? 1 : $msg->body_size; - } + else { $self->{write} = $msg->content->is_dynamic ? 1 : $msg->body_size } } return $buffer; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-7.03/lib/Mojo/UserAgent/Transactor.pm new/Mojolicious-7.05/lib/Mojo/UserAgent/Transactor.pm --- old/Mojolicious-7.03/lib/Mojo/UserAgent/Transactor.pm 2016-07-26 00:26:00.000000000 +0200 +++ new/Mojolicious-7.05/lib/Mojo/UserAgent/Transactor.pm 2016-08-21 18:02:29.000000000 +0200 @@ -71,16 +71,19 @@ my $code = $res->code // 0; return undef unless grep { $_ == $code } 301, 302, 303, 307, 308; + # CONNECT requests cannot be redirected + my $req = $old->req; + return undef if uc $req->method eq 'CONNECT'; + # Fix location without authority and/or scheme return undef unless my $location = $res->headers->location; $location = Mojo::URL->new($location); - $location = $location->base($old->req->url)->to_abs unless $location->is_abs; + $location = $location->base($req->url)->to_abs unless $location->is_abs; my $proto = $location->protocol; return undef if ($proto ne 'http' && $proto ne 'https') || !$location->host; # Clone request if necessary my $new = Mojo::Transaction::HTTP->new; - my $req = $old->req; if ($code == 307 || $code == 308) { return undef unless my $clone = $req->clone; $new->req($clone); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-7.03/lib/Mojolicious/Controller.pm new/Mojolicious-7.05/lib/Mojolicious/Controller.pm --- old/Mojolicious-7.03/lib/Mojolicious/Controller.pm 2016-07-19 02:38:18.000000000 +0200 +++ new/Mojolicious-7.05/lib/Mojolicious/Controller.pm 2016-08-27 14:19:33.000000000 +0200 @@ -106,7 +106,7 @@ my $self = shift; # WebSocket - my $tx = $self->tx; + my $tx = $self->tx || Carp::croak 'Connection already closed'; $tx->finish(@_) and return $tx->established ? $self : $self->rendered(101) if $tx->is_websocket; @@ -137,7 +137,7 @@ sub on { my ($self, $name, $cb) = @_; - my $tx = $self->tx; + my $tx = $self->tx || Carp::croak 'Connection already closed'; $self->rendered(101) if $tx->is_websocket && !$tx->established; return $tx->on($name => sub { shift; $self->$cb(@_) }); } @@ -218,8 +218,8 @@ return $self; } -sub req { shift->tx->req } -sub res { shift->tx->res } +sub req { (shift->tx || Carp::croak 'Connection already closed')->req } +sub res { (shift->tx || Carp::croak 'Connection already closed')->res } sub respond_to { my ($self, $args) = (shift, ref $_[0] ? $_[0] : {@_}); @@ -248,7 +248,7 @@ sub send { my ($self, $msg, $cb) = @_; - my $tx = $self->tx; + my $tx = $self->tx || Carp::croak 'Connection already closed'; Carp::croak 'No WebSocket connection to send message to' unless $tx->is_websocket; $tx->send($msg, $cb ? sub { shift; $self->$cb(@_) } : ()); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-7.03/lib/Mojolicious/Guides/FAQ.pod new/Mojolicious-7.05/lib/Mojolicious/Guides/FAQ.pod --- old/Mojolicious-7.03/lib/Mojolicious/Guides/FAQ.pod 2016-08-01 02:04:12.000000000 +0200 +++ new/Mojolicious-7.05/lib/Mojolicious/Guides/FAQ.pod 2016-08-27 14:23:36.000000000 +0200 @@ -259,6 +259,17 @@ defaults to C<20> seconds and can be extended with the attribute L<Mojo::Server::Prefork/"heartbeat_timeout"> if your application requires it. +=head2 What does "Connection already closed" mean? + +This error message usually appears after waiting for the results of a +non-blocking operation for longer periods of time, because the underlying +connection has been closed in the meantime and the value of the attribute +L<Mojolicious::Controller/"tx"> is no longer available. While there might not be +a way to prevent the connection from getting closed, you can also avoid this +error message by keeping a reference to the transaction object that is not +weakened. The helper L<Mojolicious::Plugin::DefaultHelpers/"delay"> will do this +automatically for you. + =head1 MORE You can continue with L<Mojolicious::Guides> now or take a look at the diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-7.03/lib/Mojolicious/Guides.pod new/Mojolicious-7.05/lib/Mojolicious/Guides.pod --- old/Mojolicious-7.03/lib/Mojolicious/Guides.pod 2016-07-19 02:38:18.000000000 +0200 +++ new/Mojolicious-7.05/lib/Mojolicious/Guides.pod 2016-08-26 19:36:13.000000000 +0200 @@ -323,6 +323,8 @@ =item * L<Mojo::Home> +=item * L<Mojo::IOLoop::Subprocess> + =item * L<Mojo::JSON::Pointer> =item * L<Mojo::Parameters> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-7.03/lib/Mojolicious/Validator/Validation.pm new/Mojolicious-7.05/lib/Mojolicious/Validator/Validation.pm --- old/Mojolicious-7.03/lib/Mojolicious/Validator/Validation.pm 2016-07-19 02:38:18.000000000 +0200 +++ new/Mojolicious-7.05/lib/Mojolicious/Validator/Validation.pm 2016-08-23 13:24:27.000000000 +0200 @@ -257,7 +257,6 @@ Change validation L</"topic">, apply filters, and make sure a value is present and not an empty string. All filters from L<Mojolicious::Validator/"FILTERS"> -are supported.All filters from L<Mojolicious::Validator/"FILTERS"> are supported. # Trim value and check size diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-7.03/lib/Mojolicious.pm new/Mojolicious-7.05/lib/Mojolicious.pm --- old/Mojolicious-7.03/lib/Mojolicious.pm 2016-08-17 18:34:19.000000000 +0200 +++ new/Mojolicious-7.05/lib/Mojolicious.pm 2016-08-29 16:00:05.000000000 +0200 @@ -43,7 +43,7 @@ has validator => sub { Mojolicious::Validator->new }; our $CODENAME = 'Doughnut'; -our $VERSION = '7.03'; +our $VERSION = '7.05'; sub AUTOLOAD { my $self = shift; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-7.03/t/mojo/subprocess.t new/Mojolicious-7.05/t/mojo/subprocess.t --- old/Mojolicious-7.03/t/mojo/subprocess.t 1970-01-01 01:00:00.000000000 +0100 +++ new/Mojolicious-7.05/t/mojo/subprocess.t 2016-08-29 17:43:27.000000000 +0200 @@ -0,0 +1,148 @@ +use Mojo::Base -strict; + +BEGIN { $ENV{MOJO_REACTOR} = 'Mojo::Reactor::Poll' } + +use Test::More; + +plan skip_all => 'set TEST_SUBPROCESS to enable this test (developer only!)' + unless $ENV{TEST_SUBPROCESS}; + +use Mojo::IOLoop; +use Mojo::IOLoop::Subprocess; + +# Huge result +my ($fail, $result); +my $subprocess = Mojo::IOLoop::Subprocess->new; +$subprocess->run( + sub { shift->pid . $$ . ('x' x 100000) }, + sub { + my ($subprocess, $err, $two) = @_; + $fail = $err; + $result .= $two; + } +); +$result = $$; +Mojo::IOLoop->start; +ok !$fail, 'no error'; +is $result, $$ . 0 . $subprocess->pid . ('x' x 100000), 'right result'; + +# Custom event loop +($fail, $result) = (); +my $loop = Mojo::IOLoop->new; +$loop->subprocess( + sub {'♥'}, + sub { + my ($subprocess, $err, @results) = @_; + $fail = $err; + $result = \@results; + } +); +$loop->start; +ok !$fail, 'no error'; +is_deeply $result, ['♥'], 'right structure'; + +# Multiple return values +($fail, $result) = (); +$subprocess = Mojo::IOLoop::Subprocess->new; +$subprocess->run( + sub { return '♥', [{two => 2}], 3 }, + sub { + my ($subprocess, $err, @results) = @_; + $fail = $err; + $result = \@results; + } +); +Mojo::IOLoop->start; +ok !$fail, 'no error'; +is_deeply $result, ['♥', [{two => 2}], 3], 'right structure'; + +# Event loop in subprocess +($fail, $result) = (); +$subprocess = Mojo::IOLoop::Subprocess->new; +$subprocess->run( + sub { + my $result; + Mojo::IOLoop->next_tick(sub { $result = 23 }); + Mojo::IOLoop->start; + return $result; + }, + sub { + my ($subprocess, $err, $twenty_three) = @_; + $fail = $err; + $result = $twenty_three; + } +); +Mojo::IOLoop->start; +ok !$fail, 'no error'; +is $result, 23, 'right result'; + +# Concurrent subprocesses +($fail, $result) = (); +Mojo::IOLoop->delay( + sub { + my $delay = shift; + Mojo::IOLoop->subprocess(sub {1}, $delay->begin); + Mojo::IOLoop->subprocess(sub {2}, $delay->begin); + }, + sub { + my ($delay, $err1, $result1, $err2, $result2) = @_; + $fail = $err1 || $err2; + $result = [$result1, $result2]; + } +)->wait; +ok !$fail, 'no error'; +is_deeply $result, [1, 2], 'right structure'; + +# No result +($fail, $result) = (); +Mojo::IOLoop::Subprocess->new->run( + sub {return}, + sub { + my ($subprocess, $err, @results) = @_; + $fail = $err; + $result = \@results; + } +); +Mojo::IOLoop->start; +ok !$fail, 'no error'; +is_deeply $result, [], 'right structure'; + +# Exception +$fail = undef; +Mojo::IOLoop::Subprocess->new->run( + sub { die 'Whatever' }, + sub { + my ($subprocess, $err) = @_; + $fail = $err; + } +); +Mojo::IOLoop->start; +like $fail, qr/Whatever/, 'right error'; + +# Non-zero exit status +$fail = undef; +Mojo::IOLoop::Subprocess->new->run( + sub { exit 3 }, + sub { + my ($subprocess, $err) = @_; + $fail = $err; + } +); +Mojo::IOLoop->start; +like $fail, qr/Storable/, 'right error'; + +# Serialization error +$fail = undef; +$subprocess = Mojo::IOLoop::Subprocess->new; +$subprocess->deserialize(sub { die 'Whatever' }); +$subprocess->run( + sub { 1 + 1 }, + sub { + my ($subprocess, $err) = @_; + $fail = $err; + } +); +Mojo::IOLoop->start; +like $fail, qr/Whatever/, 'right error'; + +done_testing(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-7.03/t/mojo/transactor.t new/Mojolicious-7.05/t/mojo/transactor.t --- old/Mojolicious-7.03/t/mojo/transactor.t 2016-07-19 02:38:18.000000000 +0200 +++ new/Mojolicious-7.05/t/mojo/transactor.t 2016-08-21 17:49:10.000000000 +0200 @@ -927,6 +927,12 @@ is $tx->res->code, undef, 'no status'; is $tx->res->headers->location, undef, 'no "Location" value'; +# 302 redirect for CONNECT request +$tx = $t->tx(CONNECT => 'http://mojolicious.org'); +$tx->res->code(302); +$tx->res->headers->location('http://example.com/bar'); +is $t->redirect($tx), undef, 'unsupported redirect'; + # Abstract methods eval { Mojo::Transaction->client_read }; like $@, qr/Method "client_read" not implemented by subclass/, 'right error'; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-7.03/t/mojolicious/app.t new/Mojolicious-7.05/t/mojolicious/app.t --- old/Mojolicious-7.03/t/mojolicious/app.t 2016-07-19 02:38:18.000000000 +0200 +++ new/Mojolicious-7.05/t/mojolicious/app.t 2016-08-27 05:40:16.000000000 +0200 @@ -16,6 +16,7 @@ use Mojo::Date; use Mojo::IOLoop; use Mojolicious; +use Mojolicious::Controller; use Test::Mojo; # Missing config file @@ -598,6 +599,20 @@ $t->get_ok('/rss.xml')->status_is(200)->content_type_is('application/rss+xml') ->content_like(qr!<\?xml version="1.0" encoding="UTF-8"\?><rss />!); +# Connection already closed +eval { Mojolicious::Controller->new->finish }; +like $@, qr/Connection already closed/, 'right error'; +eval { + Mojolicious::Controller->new->on(finish => sub { }); +}; +like $@, qr/Connection already closed/, 'right error'; +eval { Mojolicious::Controller->new->req }; +like $@, qr/Connection already closed/, 'right error'; +eval { Mojolicious::Controller->new->res }; +like $@, qr/Connection already closed/, 'right error'; +eval { Mojolicious::Controller->new->send('whatever') }; +like $@, qr/Connection already closed/, 'right error'; + # Abstract methods eval { Mojolicious::Plugin->register }; like $@, qr/Method "register" not implemented by subclass/, 'right error';
