File Coverage

blib/lib/Twiggy/Prefork/Server.pm
Criterion Covered Total %
statement 53 54 98.1
branch 9 10 90.0
condition 3 4 75.0
subroutine 12 12 100.0
pod 0 2 0.0
total 77 82 93.9


line stmt bran cond sub pod time code
1             package Twiggy::Prefork::Server;
2              
3 62     62   33047 use strict;
  62         84  
  62         2694  
4 62     62   378 use warnings;
  62         95  
  62         1862  
5 62     62   1280 use parent qw/Twiggy::Server/;
  62         652  
  62         2066  
6 62     62   2713098 use Parallel::Prefork;
  62         252062  
  62         660  
7              
8 62     62   3072 use constant DEBUG => $ENV{TWIGGY_DEBUG};
  62         115  
  62         29834  
9              
10             sub new {
11 63     63 0 1654 my ($class, %args) = @_;
12 63         488 my $self = $class->SUPER::new(%args);
13              
14 63   100     1241 $self->{max_workers} = $args{max_workers} || 10;
15 63 100       274 $self->{max_reqs_per_child} = defined $args{max_reqs_per_child} ? $args{max_reqs_per_child} : 100;
16 63   50     849 $self->{min_reqs_per_child} = $args{min_reqs_per_child} || 0;
17              
18 63         322 $self;
19             }
20              
21             sub _run_app {
22 174     174   824030 my($self, $app, $env, $sock) = @_;
23 174         542 $env->{'psgix.exit_guard'} = $self->{exit_guard};
24 174         1600 $self->SUPER::_run_app($app, $env, $sock);
25             }
26              
27             sub _accept_handler {
28 60     60   2207 my $self = shift;
29              
30 60         353 my $cb = $self->SUPER::_accept_handler( @_ );
31             return $self->{max_reqs_per_child} == 0 ? $cb : sub {
32 112     112   2192477 my ( $sock, $peer_host, $peer_port ) = @_;
33 112         488 $self->{reqs_per_child}++;
34 112         1187 $cb->( $sock, $peer_host, $peer_port );
35              
36 112 100       35226 if ( $self->{reqs_per_child} > $self->{max_reqs_per_child} ) {
37 5         11 DEBUG && warn "[$$] reach max reqs per child\n";
38 5         54 my $listen_guards = delete $self->{listen_guards};
39 5         19 undef $listen_guards; #block new accept
40 5         151 $self->{exit_guard}->end;
41             }
42 60 100       1065 };
43             }
44              
45             sub run {
46 60     60 0 97 my $self = shift;
47 60         352 $self->register_service(@_);
48             my $pm = Parallel::Prefork->new({
49             max_workers => $self->{max_workers},
50             trap_signals => {
51             TERM => 'TERM',
52             HUP => 'TERM',
53             },
54             before_fork => sub {
55 310 50   310   2332512 if ( $self->{min_reqs_per_child} ) {
56 0         0 $self->{max_reqs_per_child} = $self->{min_reqs_per_child}
57             + int(rand( $self->{max_reqs_per_child} - $self->{min_reqs_per_child}));
58             }
59             },
60 60         241069 });
61              
62 60         2907 while ($pm->signal_received ne 'TERM') {
63 63 100       2783654 $pm->start and next;
64 53         52896 DEBUG && warn "[$$] start child";
65 53         823 my $exit = $self->{exit_guard};
66 53         1472 delete $SIG{TERM};
67 53         596 my $w; $w = AE::signal TERM => sub {
68 48     48   11214135 warn "[$$] recieved signal TERM" if DEBUG;
69 48         2246 $exit->end;
70 48         16994 undef $w
71 53         3348 };
72 53         3411 $exit->recv;
73 53         5116 DEBUG && warn "[$$] end child";
74 53         694 $pm->finish;
75             }
76 7         2153908 $pm->wait_all_children;
77             }
78              
79             1;
80              
81             __END__