Blog

How to manage Gearman worker processes.

http://www.pqpq.de/mt/2010/01/gearmandriver.html
^^ I don't like this approach.

Gearman のワーカーの管理はこういう風にするのが個人的にはおすすめ。

Gearman::Driver is too heavy framwork for me.
(and, workers should save the memory, but Gearman::Driver itself uses too much memory!)

というわけで、I wrote sample startup script for Gearman(not tested).

なお、個人的に libgearman のリリースポリシーやら品質やらを*まだ*信頼してないので Gearman::Worker をつかってみた。

use strict;
use warnings;
use Gearman::Worker;
use Getopt::Long;
use Parallel::Prefork;
use Pod::Usage;
use UNIVERSAL::require;
use Class::Inspector;

my $max_workers            = 10;
my $max_requests_per_child = 100;
GetOptions(
    's|server=s@'              => \my $servers,
    'prefix=s'                 => \my $prefix,
    'max-workers=i'            => \$max_workers,
    'max-requests-per-child=i' => \$max_requests_per_child,
    'h|help'                   => \my $help,
) or pod2usage();
pod2usage() unless $servers && @$servers;
pod2usage() if $help;

my $pm = Parallel::Prefork->new(
    {
        max_workers  => $max_workers,
        trap_signals => {
            TERM => 'TERM',
            HUP  => 'TERM',
            USR1 => undef,
        }
    }
);
while ( $pm->signal_received ne 'TERM' ) {
    $pm->start and next;

    my $worker = Gearman::Worker->new();
    $worker->job_servers(@$servers);
    $worker->prefix($prefix) if $prefix;
    for my $klass (@ARGV) {
        $klass->use or die $@;
        my @jobs = grep /^job_/, Class::Inspector->functions($klass);
        for my $job (@jobs) {
            (my $job_name = $job) =~ s/^job_//; # Sledgeish dispatching
            $worker->register_function($job_name, $klass->can($job));
        }
    }

    my $i = 0;
    while ($i++ < $max_requests_per_child) {
        $worker->work();
    }

    $pm->finish;
}

$pm->wait_all_children();

__END__

=head1 SYNOPSIS

    % gearman-starter.pl --server=127.0.0.1 MyApp::Worker::Foo

【Updated at 20110121】
Create instance of Gearman::Worker after forking process(reported by chiba++)