読者です 読者をやめる 読者になる 読者になる

Deamon::Generic で TheSchwartz の worker をデーモン化する(1)

TheSchwartz の worker をデーモンにしたくて、どうしようかと。daemontools でもいいんだろうけど、CPAN で見つけた Daemon::Generic を使ってみた。
まず TheSchwartz の client (jobを投入する) と worker (jobを実行する) モジュールを普通に作る。

#!/usr/bin/perl
# client.pl
use strict;
use TheSchwartz;
use YAML qw/ LoadFile /;
my $client = TheSchwartz->new( %{ LoadFile(shift) } );
$client->insert( 'MyWorker' => { t => time } );
package MyWorker;
use strict;
use base qw/ TheSchwartz::Worker /;
use JSON::Syck;
sub work {
    my $class = shift;
    my $job   = shift;
    printf "jobid: %d: arg=%s\n", $job->jobid, JSON::Syck::Dump($job->arg);
    $job->completed();
}
1;

TheSchwartz の new に渡す引数は YAML で別ファイルにした。
さて、worker デーモンを Daemon::Generic を使って書くと以下のようになる。

#!/usr/bin/perl
# workerd.pl
use strict;
use TheSchwartz;
use MyWorker;
use Daemon::Generic;
use YAML qw/ LoadFile /;

newdaemon(
    progname   => 'workerd',
    pidfile    => '/var/tmp/workerd.pid',
    configfile => 'config.yml',
);

my $config;
sub gd_run {
    print "starting MyWorker\n";
    my $client = TheSchwartz->new(%{ $config });
    $client->can_do('MyWorker');
    $client->work();
}

sub gd_preconfig {
    my $self = shift;
    $config = LoadFile $self->{configfile};
    return;
}

gd_run に実際に実行する処理を記述。gd_preconfig には statrt / reload の際に設定ファイルのパスが渡ってくるので、それを適宜処理するコードを記述。
引数なしで実行すると以下のような Usage が出る。

$ perl workerd.pl                        
Usage: workerd [ -c file ] [ -f ] { start | stop | reload | restart | check | help | version } 
 -c file         Specify configuration file (instead of /etc/workerd.conf)
 -f              Run in the foreground (don't detach)
 start           Starts a new workerd if there isn't one running already
 stop            Stops a running workerd
 reload          Causes a running workerd to reload it's config file.  Starts
                 a new one if none is running.
 restart         Stops a running workerd if one is running.  Starts a new one.
 check           Check the configuration file and report the daemon state
 help            Display this usage info
 version         Display the version of workerd

 -c で設定ファイルを変更、-f でデーモン化せずにフォアグラウンドで実行。
標準出力と標準エラー出力に出力した内容は、デフォルトでは logger コマンドに渡されて syslog に記録されます。

$ perl workerd.pl start    # 開始
Starting workerd server

$ perl client.pl config.yml # jobを突っ込む

$ perl workerd.pl stop     # 終了
Killing 10513

syslog はこんな感じ。

Sep 13 03:31:10 hostname workerd[10515]: Sucessfully daemonized\n
Sep 13 03:31:10 hostname workerd[10515]: Starting up...\n
Sep 13 03:31:10 hostname workerd[10515]: Starting MyWorker\n
Sep 13 03:31:35 hostname workerd[10515]: jobid: 32: arg={"t":1189621891}\n
Sep 13 03:31:58 hostname workerd[10515]: Quitting...\n

デーモン化して開始、ログ取得、停止などが簡単に操作できる。