File Coverage

blib/lib/Coro/ProcessPool/Util.pm
Criterion Covered Total %
statement 79 105 75.2
branch 14 34 41.1
condition 4 8 50.0
subroutine 18 18 100.0
pod 0 5 0.0
total 115 170 67.6


line stmt bran cond sub pod time code
1             package Coro::ProcessPool::Util;
2             # ABSTRACT: Utility functions and constants used by Coro::ProcessPool
3             $Coro::ProcessPool::Util::VERSION = '0.28';
4 5     5   155564 use strict;
  5         15  
  5         144  
5 5     5   25 use warnings;
  5         12  
  5         121  
6 5     5   20 use Carp;
  5         11  
  5         885  
7 5     5   27 use Config;
  5         10  
  5         155  
8 5     5   2117 use Const::Fast;
  5         13213  
  5         28  
9 5     5   4704 use Data::Dump::Streamer;
  5         349223  
  5         54  
10 5     5   2809 use MIME::Base64 qw(encode_base64 decode_base64);
  5         3158  
  5         324  
11 5     5   2897 use String::Escape qw(backslash);
  5         38570  
  5         388  
12 5     5   37 use Sereal::Encoder qw(sereal_encode_with_object);
  5         14  
  5         251  
13 5     5   29 use Sereal::Decoder qw(sereal_decode_with_object);
  5         9  
  5         228  
14              
15 5     5   1311 use parent 'Exporter';
  5         1282  
  5         27  
16              
17             our @EXPORT_OK = qw(
18             get_command_path
19             get_args
20             cpu_count
21             encode
22             decode
23             $EOL
24             $CPUS
25             );
26              
27             const our $EOL => "\n";
28             const our $CPUS => cpu_count();
29              
30             my $ENCODER = Sereal::Encoder->new();
31             my $DECODER = Sereal::Decoder->new();
32              
33             sub encode {
34 22     22 0 5951   my ($id, $info, $data) = @_;
35 22 50       71   $data = [] unless defined $data;
36              
37 22         107   my $package = {
38                 id => $id,
39                 data => $data,
40                 info => undef,
41                 code => undef,
42               };
43              
44 22 100 66     111   if (ref $info && ref $info eq 'CODE') {
45 15         71     $package->{code} = Dump($info)->Purity(1)->Declare(1)->Indent(0)->Out;
46               } else {
47 7         16     $package->{info} = $info;
48               }
49              
50 22         23366   my $pickled = sereal_encode_with_object($ENCODER, $package);
51 22         574   encode_base64 $pickled, '';
52             }
53              
54             sub decode {
55 17 50   17 0 42   my $line = shift or croak 'decode: expected line';
56 17         49   my $pickled = decode_base64($line);
57 17         92   sereal_decode_with_object($DECODER, $pickled, my $package);
58              
59 17         44   my ($id, $info, $data) = @{$package}{qw(id info data)};
  17         38  
60              
61               $info = eval "do{ $package->{code} }" ## no critic
62 1 100   1   6     if $package->{code};
  1     1   2  
  1         29  
  1         5  
  1         2  
  1         33  
  17         114  
63              
64 17         68   return ($id, $info, $data);
65             }
66              
67             sub get_command_path {
68 23     23 0 975   my $perl = $Config{perlpath};
69 23         279   my $ext = $Config{_exe};
70 23 50 33     478   $perl .= $ext if $^O ne 'VMS' && $perl !~ /$ext$/i;
71 23         85   return $perl;
72             }
73              
74             sub get_args {
75 23     23 0 141   my @inc = map { sprintf('-I%s', backslash($_)) } @_, @INC;
  254         2781  
76 23         270   my $cmd = q|-MCoro::ProcessPool::Worker -e 'Coro::ProcessPool::Worker::run()'|;
77 23         121   return join ' ', @inc, $cmd;
78             }
79              
80             #-------------------------------------------------------------------------------
81             # "Borrowed" from Test::Smoke::Util::get_ncpus.
82             #
83             # Modifications:
84             # * Use $^O in place of an input argument
85             # * Return number instead of string
86             #-------------------------------------------------------------------------------
87             sub cpu_count {
88             # Only *nixy osses need this, so use ':'
89 5     5 0 51   local $ENV{PATH} = "$ENV{PATH}:/usr/sbin:/sbin";
90              
91 5         11   my $cpus = "?";
92               OS_CHECK: {
93 5         8     local $_ = $^O;
  5         14  
94              
95 5 50       26     /aix/i && do {
96 0         0       my @output = `lsdev -C -c processor -S Available`;
97 0         0       $cpus = scalar @output;
98 0         0       last OS_CHECK;
99                 };
100              
101 5 50       36     /(?:darwin|.*bsd)/i && do {
102 0         0       chomp( my @output = `sysctl -n hw.ncpu` );
103 0         0       $cpus = $output[0];
104 0         0       last OS_CHECK;
105                 };
106              
107 5 50       17     /hp-?ux/i && do {
108 0         0       my @output = grep /^processor/ => `ioscan -fnkC processor`;
109 0         0       $cpus = scalar @output;
110 0         0       last OS_CHECK;
111                 };
112              
113 5 50       16     /irix/i && do {
114 0         0       my @output = grep /\s+processors?$/i => `hinv -c processor`;
115 0         0       $cpus = (split " ", $output[0])[0];
116 0         0       last OS_CHECK;
117                 };
118              
119 5 50       18     /linux/i && do {
120 5         10       my @output; local *PROC;
  5         13  
121 5 50       264       if ( open PROC, "< /proc/cpuinfo" ) { ## no critic
122 5         1821         @output = grep /^processor/ => <PROC>;
123 5         159         close PROC;
124                   }
125 5 50       25       $cpus = @output ? scalar @output : '';
126 5         35       last OS_CHECK;
127                 };
128              
129 0 0       0     /solaris|sunos|osf/i && do {
130 0         0       my @output = grep /on-line/ => `psrinfo`;
131 0         0       $cpus = scalar @output;
132 0         0       last OS_CHECK;
133                 };
134              
135 0 0       0     /mswin32|cygwin/i && do {
136                   $cpus = exists $ENV{NUMBER_OF_PROCESSORS}
137 0 0       0         ? $ENV{NUMBER_OF_PROCESSORS} : '';
138 0         0       last OS_CHECK;
139                 };
140              
141 0 0       0     /vms/i && do {
142 0         0       my @output = grep /CPU \d+ is in RUN state/ => `show cpu/active`;
143 0 0       0       $cpus = @output ? scalar @output : '';
144 0         0       last OS_CHECK;
145                 };
146              
147 0         0     $cpus = "";
148 0         0     require Carp;
149 0         0     Carp::carp( "get_ncpu: unknown operationg system" );
150               }
151              
152 5   50     59   return sprintf '%d', ($cpus || 1);
153             }
154              
155             1;
156              
157             __END__
158            
159             =pod
160            
161             =encoding UTF-8
162            
163             =head1 NAME
164            
165             Coro::ProcessPool::Util - Utility functions and constants used by Coro::ProcessPool
166            
167             =head1 VERSION
168            
169             version 0.28
170            
171             =head1 AUTHOR
172            
173             Jeff Ober <sysread@fastmail.fm>
174            
175             =head1 COPYRIGHT AND LICENSE
176            
177             This software is copyright (c) 2017 by Jeff Ober.
178            
179             This is free software; you can redistribute it and/or modify it under
180             the same terms as the Perl 5 programming language system itself.
181            
182             =cut
183