Perlが提供するデーモンのフレームワーク
Ubuntu 14.10のパッケージで、perlとdaemonをキーに検索すると、以下がヒットします。
この中でも私がデーモンの実装に便利だと感じたlibdaemon-generic-perlが提供するDaemon::Genericを紹介します。
libhttp-daemon-perl - simple http server class
libapp-daemon-perl - Perl module to start an Application as a Daemon
libdaemon-control-perl - module for creating init scripts in Perl
libdaemon-generic-perl - framework to provide start/stop/reload for a daemon
libhttp-daemon-ssl-perl - A simple HTTP server class with SSL support
libnet-daemon-perl - Perl module for building portable Perl daemons easily
libproc-daemon-perl - module for running scripts as daemons
libmoosex-daemonize-perl - Moose ベースのアプリケーションをデーモン化するモジュール
Daemon::Genericの特徴
Daemon::Genericは、以下の特徴を持ちます。
-
Object Orientedで実装したフレームワークを提供
- メイン処理部分メソッド(gd_run)をオーバライドすることで、手早くオリジナルのデーモンを作成可能
-
System-Vスタイルに沿った以下のコマンドを標準提供
- start
- デーモンがランニング状態でない場合、デーモンを開始します。
- stop
- デーモンを停止します。
- reload
- コンフィグレーション・ファイルの再読み込みします。
- restart
- 実行中のデーモンを停止して、新しいインスタンスのデーモンを開始します。
- check
- コンフィグレーション・ファイルのチェックを行って、デーモンの状態を表示します。
- help
- 使用方法を表示します。
- version
- バージョン情報を表示します。
- install
- root権限でコールすると、System-Vスタイルのスクリプトとして/etc/init.d配下へのシンボリック・リンクを張ります。
- uninstall
- root権限でコールすると、/etc/init.d配下へのシンボリック・リンクを削除します。
Daemon::Genericのインストール
以下のコマンドを実行するのみです。
$ sudo apt-get install libdaemon-generic-perl
Daemon::Genericの実装
Daemon::Genericの使用方法
Daemon::Genericで、デーモンを実装するには、gd_runメソッドをオーバーライドして、newdaemonをコールするだけです。
ただし、gd_runの中身は、無限ループにする必要があります。例えば、以下のように。
#!/usr/bin/perl
use Daemon::Generic;
sub gd_run {
while(1) {
# write main routine here
sleep(60);
}
}
newdaemon();
Daemon::Genericでユーザデーモンを実装するために
Daemon::Genericは、System-Vスタイルの慣例に従って、デーモン実行時のpid情報を/var/run配下に保存しようとします。しかし、一般ユーザ権限では、/var/run配下への書き込み権限がないため、デーモンの実行に失敗します。
Daemon::Genericでは、newdaemonの引数に、pidfile
キーとその値を指定することで、pidの保存先を変更することができます。例えば、$HOME配下に隠しファイルとしてpidファイルを準備するには、以下のように指定します。
sub gd_run {
# ...
}
newdaemon(pilfile => $ENV{HOME} . "/.mydaemonPid");
ただし、将来的にコンフィグレーション・ファイルを使用予定がある場合は、progname
キーとpidbase
キーを使用することをお勧めします。指定方法の詳細は、man Daemon::Generic
でオンライン・マニュアル参照してください。
Daemon::Genericの実装例
最後に、Daemon::Genericの実装例として、30秒毎にエポックタイムを画面通知するユーザデーモンのソースコードを以下に示します。
#!/usr/bin/perl -w
use 5.14.1;
use strict;
use utf8;
use Daemon::Generic;
use File::Basename;
sub gd_run {
while(1) {
system('/usr/bin/notify-send', 'DaemonTest', 'Epocime in seconds from 1970/1/1: ' . time);
sleep(30);
}
}
my $prg;
($prg) = fileparse($0);
my $pidfile = $ENV{HOME} . "/." . $prg . "_pid";
newdaemon(pidfile => $pidfile);
そして、実行方法は、以下となります。
$ ./daemon.pl start