$shibayu36->blog;

株式会社はてなでエンジニアをしています。プログラミングや読書のことなどについて書いています。

手元開発環境でサーバを起動時のみcronのようにスクリプトを実行する(Perlの場合)

これまでPerlを利用した手元開発環境でどのようにcronを動かすか迷ってきたのだけど、その解決策が見つかったのでメモ。

課題

  • 開発サーバや本番サーバではcronで定期的にスクリプトが実行されている
  • 定期的に実行されているスクリプトが動かないと、正しく動かない機能がある
    • 例えば予約投稿みたいな機能など
  • しかし手元開発環境ではcronのように定期的にスクリプトを実行していなかった
  • 結果として、手元開発環境で手動でスクリプトを動かさないと確認できない機能があった

解決策として手元でもcrontabを書く方法もあるのだけど、この場合開発していない時も勝手に実行されるので避けたかった。

解決方法

実はProclet というツールに、サーバを起動しながら定期的に指定したコードを実行してくれる機能があるということに気づいた。詳しくはSYNOPSISを参照。

これを使ってcronに指定しているスクリプトを適当に実行するようにしてみる。

script/server.pl

use Plack::Loader;
use Proclet;

my $proclet = Proclet->new(
    color => 1
);

# サーバー起動
$proclet->service(
    code => sub {
        my $loader = Plack::Loader->load(
            'Starlet',
            port        => 3000,
            max_workers => 4,
        );
        my $app = sub {
            return [
                200,
                [ 'Content-Type' => 'text/plain' ],
                [ "200 OK" ]
            ];
        };
        $loader->run($app);
    },
    tag => 'web'
);

# cronスクリプトを登録
$proclet->service(
    code => sub {
        system "perl script/cron/hoge.pl";
    },
    tag => 'cron.hoge',
    every => '*/1 * * * *', # サーバ起動時だけ1分に1回実行
);
$proclet->service(
    code => sub {
        system "perl script/cron/fuga.pl";
    },
    tag => 'cron.fuga',
    every => '*/5 * * * *', # サーバ起動時だけ5分に1回実行
);

$proclet->run;

後はこのスクリプトを起動して、手元開発をすれば、サーバを起動しながら1分に1回script/cron/hoge.plが、5分に1回script/cron/fuga.plが実行されるようになる。最高。