File Coverage

blib/lib/Plack/Loader/Shotgun.pm
Criterion Covered Total %
statement 45 45 100.0
branch 2 2 100.0
condition n/a
subroutine 9 9 100.0
pod 0 2 0.0
total 56 58 96.5


line stmt bran cond sub pod time code
1             package Plack::Loader::Shotgun;
2 38     38   12966170 use strict;
  38         114  
  38         2128  
3 38     38   342 use parent qw(Plack::Loader);
  38         76  
  38         380  
4 38     38   3458 use Storable;
  38         76  
  38         3382  
5 38     38   266 use Try::Tiny;
  38         114  
  38         2736  
6 38     38   25156 use Plack::Middleware::BufferedStreaming;
  38         152  
  38         20064  
7              
8             die <
9              
10             Shotgun loader uses fork(2) system call to create a fresh Perl interpreter, that is known to not work
11             properly in a fork-emulation layer on Windows and cause huge memory leaks.
12              
13             If you're aware of this and still want to run the loader, run it with the environment variable
14             PLACK_SHOTGUN_MEMORY_LEAK on.
15              
16             DIE
17              
18             sub preload_app {
19 37     37 0 2405 my($self, $builder) = @_;
20 37     37   4588 $self->{builder} = sub { Plack::Middleware::BufferedStreaming->wrap($builder->()) };
  37         1529  
21             }
22              
23             sub run {
24 37     37 0 407 my($self, $server) = @_;
25              
26             my $app = sub {
27 703     703   4273 my $env = shift;
28              
29 703         35051 pipe my $read, my $write;
30              
31 703         2561764 my $pid = fork;
32 703 100       60435 if ($pid) {
33             # parent
34 666         64133 close $write;
35 666         8302821 my $res = Storable::thaw(join '', <$read>);
36 666         89660 close $read;
37 666         934399955 waitpid($pid, 0);
38              
39 666         39119 return $res;
40             } else {
41             # child
42 37         6748 close $read;
43              
44 37         2425 my $res;
45             try {
46 37         28628 $env->{'psgi.streaming'} = 0;
47 37         4172 $res = $self->{builder}->()->($env);
48 36         38545 my @body;
49 36         28321 Plack::Util::foreach($res->[2], sub { push @body, $_[0] });
  39         1265  
50 36         4531 $res->[2] = \@body;
51             } catch {
52 1         279 $env->{'psgi.errors'}->print($_);
53 1         73 $res = [ 500, [ "Content-Type", "text/plain" ], [ "Internal Server Error" ] ];
54 37         15471 };
55              
56 37         2039 print {$write} Storable::freeze($res);
  37         1970  
57 37         16449 close $write;
58 37         46733 exit;
59             }
60 37         999 };
61              
62 37         296 $server->run($app);
63             }
64              
65             1;
66              
67             __END__