Gearman::Worker と Parallel::Prefork の組み合わせ
こちらを参考に。
use strict; use warnings; use Gearman::Worker; use Parallel::Prefork; use Storable qw( thaw ); use List::Util qw( sum ); use Perl6::Say; sub MaxRequestsPerChild () { 60 } my $pm = Parallel::Prefork->new({ max_workers => 3, trap_signals => { TERM => 'TERM', HUP => 'TERM', }, }); my $worker = Gearman::Worker->new; $worker->job_servers("localhost"); $worker->register_function(sum => sub { sum @{ thaw($_[0]->arg) } }); { $pm->start and last; say "spawn $$"; my $reqs_before_exit = MaxRequestsPerChild; $SIG{TERM} = sub { $reqs_before_exit = 0 }; sleep 1; # すぐに働くと、たまにちゃんとjob処理しないので。 $worker->work( on_start => sub { --$reqs_before_exit }, stop_if => sub { ! $reqs_before_exit > 0 }, ); say "FINISHED $$"; $pm->finish; } $pm->wait_all_children;
どうもこれ↓だとダメぽい。
while ( $reqs_before_exit > 0 ) { $worker->work( on_start => sub { --$reqs_before_exit } ); }
よく*1'$worker->work() while 1'とか見るけど、あれ意味ないような。workするだけで、中で無限ループってる気がする。
*1:podでも