File Coverage

blib/lib/Mojolicious/Plugin/Subprocess.pm
Criterion Covered Total %
statement 21 21 100.0
branch 3 4 75.0
condition 1 2 50.0
subroutine 4 4 100.0
pod 1 1 100.0
total 30 32 93.7


line stmt bran cond sub pod time code
1             package Mojolicious::Plugin::Subprocess;
2              
3 1     1   805 use Mojo::Base 'Mojolicious::Plugin';
  1         2  
  1         6  
4 1     1   192 use Mojo::IOLoop;
  1         2  
  1         8  
5              
6             our $VERSION = '1.000';
7              
8             sub register {
9 1     1 1 37 my ($self, $app, $options) = @_;
10            
11 1   50     2 my %subprocess_args = %{$options // {}};
  1         4  
12 1         3 my $use_sereal = delete $subprocess_args{use_sereal};
13            
14             $app->helper(subprocess => sub {
15 3     3   102075 my ($c, $child, $parent) = @_;
16            
17 3         23 my $subprocess = Mojo::IOLoop->subprocess;
18 3         134 $subprocess->$_($subprocess_args{$_}) for
19 9         26 grep { exists $subprocess_args{$_} } qw(deserialize ioloop serialize);
20 3 50       11 $subprocess->with_roles('Mojo::IOLoop::Subprocess::Role::Sereal')
21             ->with_sereal if $use_sereal;
22            
23             $c->delay(sub {
24 3         1639 $subprocess->run($child, shift->begin);
25             }, sub {
26 3         33637 my ($delay, $err, @results) = @_;
27 3 100       29 die $err if $err;
28 2         22 $c->$parent(@results);
29 3         53 });
30 1         9 });
31             }
32              
33             1;
34              
35             =head1 NAME
36              
37             Mojolicious::Plugin::Subprocess - Subprocesses in Mojolicious applications
38              
39             =head1 SYNOPSIS
40              
41             use Mojolicious::Lite;
42            
43             plugin 'Subprocess';
44            
45             get '/slow' => sub {
46             my $c = shift;
47             $c->subprocess(sub {
48             return do_slow_stuff();
49             }, sub {
50             my ($c, @results) = @_;
51             $c->render(json => \@results);
52             });
53             };
54            
55             # or use Sereal as serializer
56             plugin 'Subprocess' => {use_sereal => 1};
57              
58             =head1 DESCRIPTION
59              
60             L is a L plugin that adds a
61             L helper method to your application, which uses
62             L to perform computationally expensive operations in
63             subprocesses without blocking the event loop.
64              
65             The option C (requires L)
66             will use L for data serialization, which is faster than L and
67             supports serialization of more reference types such as C. The
68             L is supported to control
69             serialization of blessed objects.
70              
71             Any other options passed to the plugin will be used as attributes to build the
72             L object.
73              
74             Note that it does not increase the timeout of the connection, so if your forked
75             process is going to take a very long time, you might need to increase that
76             using L.
77              
78             =head1 HELPERS
79              
80             L implements the following helpers.
81              
82             =head2 subprocess
83              
84             $c->subprocess(sub {
85             my $subprocess = shift;
86             ...
87             }, sub {
88             my ($c, @results) = @_;
89             ...
90             });
91              
92             Execute the first callback in a child process with
93             L, and execute the second callback in the
94             parent process with the results. The callbacks are executed via
95             L, which disables automatic
96             rendering, keeps a reference to the transaction, and renders an exception
97             response if an exception is thrown in either callback. This also means that the
98             parent callback will not be called if an exception is thrown in the child
99             callback.
100              
101             =head1 METHODS
102              
103             L inherits all methods from
104             L and implements the following new ones.
105              
106             =head2 register
107              
108             $plugin->register(Mojolicious->new);
109             $plugin->register(Mojolicious->new, {ioloop => $ioloop});
110              
111             Register helper in L application.
112              
113             =head1 BUGS
114              
115             Report any issues on the public bugtracker.
116              
117             =head1 AUTHOR
118              
119             Dan Book
120              
121             =head1 COPYRIGHT AND LICENSE
122              
123             This software is Copyright (c) 2016 by Dan Book.
124              
125             This is free software, licensed under:
126              
127             The Artistic License 2.0 (GPL Compatible)
128              
129             =head1 SEE ALSO
130              
131             L, L