FuelPHPのデーモンパッケージ

Webアプリを作っている時に、バックグラウンドで処理をしたい事があるかと思います。

今回、Gearmanのworkerを動かそうと思ったのですが、
Unix系OSPHPでは

php oil refine ほげほげ &

としても、うまく動きません。

そこで、デーモンを動かすようにバックグラウンドで処理を行うパッケージを作ってみました。

正直に言うと<fuelphpのバックグラウンドプロセスパッケージ>のパクリです。ただ、あちらはUnix系では動かないので…

設置

次の位置においてください
FuelPHP Daemon package
/fuel/packages/daemon
なお、このパッケージを動かすためには、PHPのpcntlとposixが有効になっている必要があります。

config.phpを編集

daemonをAPPPATH/config/config.php の always_load の部分に追加します

return array(
    'always_load' => array(
        'packages' => array(
            'daemon', // 追加
        ),
    )
);

使用例

<?php

namespace Fuel\Tasks;

class Daemontest
{

    public function run()
    {
        \Daemon\Daemon::forge()->setCallback('\\Fuel\\Tasks\\Daemontest::callback')->run();
    }

    public static function callback()
    {
        while(TRUE){
            //ここにいろいろな処理を書く
            sleep(1);
        }
    }
}

注意点とか

Windowsでは動きません

動作のしくみ

run()が呼ばれたときには下図プロセス1しかありません。

f:id:harul:20120811234120p:plain

まずプロセス1からfork()して子プロセス2の生成

f:id:harul:20120811234124p:plain

そのプロセス2をsetsid()にて新しいセッションに移す。

f:id:harul:20120811234126p:plain

その後、プロセス1は終了し、またプロセス2はfork()を行ってプロセス3を生成。

セッションリーダとなるプロセスが残っていると、端末に紐付することができてしまうので、
プロセス2は終了。

f:id:harul:20120811234129p:plain

最後に、プロセス3にてfork()を行い、子プロセス4にてcallbackの呼び出しを行っています。

この状態で、プロセス3にSIGTERMが呼ばれた場合には、
プロセス4にSIGINTを送っています。

書いてもいまいちわかりにくいですね。申し訳ない。

次はGearmanのパッケージを作ります。