File Coverage

blib/lib/Parallel/Prefork/SpareWorkers.pm
Criterion Covered Total %
statement 47 51 92.1
branch 8 10 80.0
condition 7 13 53.8
subroutine 13 14 92.8
pod 3 4 75.0
total 78 92 84.7


line stmt bran cond sub pod time code
1             package Parallel::Prefork::SpareWorkers;
2              
3 1     1   560 use strict;
  1         1  
  1         24  
4 1     1   3 use warnings;
  1         1  
  1         26  
5              
6 1     1   2 use Exporter qw(import);
  1         1  
  1         23  
7              
8 1     1   473 use List::MoreUtils qw(uniq);
  1         7494  
  1         5  
9              
10 1     1   411 use base qw/Parallel::Prefork/;
  1         1  
  1         365  
11              
12 1     1   4 use constant STATUS_NEXIST => '.';
  1         1  
  1         68  
13 1     1   3 use constant STATUS_IDLE => '_';
  1         2  
  1         339  
14              
15             our %EXPORT_TAGS = (
16             status => [ qw(STATUS_NEXIST STATUS_IDLE) ],
17             );
18             our @EXPORT_OK = uniq sort map { @$_ } values %EXPORT_TAGS;
19             $EXPORT_TAGS{all} = \@EXPORT_OK;
20              
21             __PACKAGE__->mk_accessors(qw/min_spare_workers max_spare_workers scoreboard heartbeat/);
22              
23             sub new {
24 1     1 1 1046 my $klass = shift;
25 1         6 my $self = $klass->SUPER::new(@_);
26             die "mandatory option min_spare_workers not set"
27 1 50       3 unless $self->{min_spare_workers};
28 1   33     3 $self->{max_spare_workers} ||= $self->max_workers;
29 1   50     6 $self->{heartbeat} ||= 0.25;
30 1   33     2 $self->{scoreboard} ||= do {
31 1         400 require 'Parallel/Prefork/SpareWorkers/Scoreboard.pm';
32             Parallel::Prefork::SpareWorkers::Scoreboard->new(
33             $self->{scoreboard_file} || undef,
34 1   50     18 $self->max_workers,
35             );
36             };
37 1         4 $self;
38             }
39              
40             sub start {
41 1     1 1 8 my $self = shift;
42 1         5 my $ret = $self->SUPER::start();
43 1 50       5 unless ($ret) {
44             # child process
45 0         0 $self->scoreboard->child_start();
46 0         0 return;
47             }
48 1         3 return 1;
49             }
50              
51             sub num_active_workers {
52 99     99 0 172 my $self = shift;
53             scalar grep {
54 99 100       347 $_ ne STATUS_NEXIST && $_ ne STATUS_IDLE
  990         5900  
55             } $self->scoreboard->get_statuses;
56             }
57              
58             sub set_status {
59 0     0 1 0 my ($self, $status) = @_;
60 0         0 $self->scoreboard->set_status($status);
61             }
62              
63             sub _decide_action {
64 95     95   125 my $self = shift;
65 95         264 my $spare_workers = $self->num_workers - $self->num_active_workers;
66 95 100 100     442 return 1
67             if $spare_workers < $self->min_spare_workers
68             && $self->num_workers < $self->max_workers;
69 83 100       535 return -1
70             if $spare_workers > $self->max_spare_workers;
71 73         500 return 0;
72             }
73              
74             sub _on_child_reap {
75 10     10   30 my ($self, $exit_pid, $status) = @_;
76 10         45 $self->SUPER::_on_child_reap($exit_pid, $status);
77 10         27 $self->scoreboard->clear_child($exit_pid);
78             }
79              
80             sub _max_wait {
81 45     45   48 my $self = shift;
82 45         113 return $self->{heartbeat};
83             }
84              
85             1;
86             __END__