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
デーモン化して開始、ログ取得、停止などが簡単に操作できる。