これは Perl Advent Calendar 2017 の 10日目の記事です。

昨日は @ytnobodyさんの Perlコアモジュールに寄せてみる でした。コアモジュール縛り、たまに必要になるんですが、近年の Perl だとコアにも便利機能が結構ありますよね。

今回は Minion というジョブキューを紹介しようと思います。

ジョブキューについて

「ジョブキューて何?」という方は以下の記事など見ると良いかと思います。

2011年の記事なので、少し内容が古いかもしれませんが、基本的なことは網羅されていると思います。また、Minion は比較的新しい(2014年リリース)なので、ここでは取り上げられていませんが、使い方、できることなどはだいたい同じです。

とはいえ、「だいたい同じ」では新しいものを作る必然性もあまりないわけで、Minion には Minion ならではの特長もあります。

Minion の特長

  • アクティブに開発されている
    • 毎月新バージョンが出ている感じで、メジャーバージョンアップも頻繁です
    • なので、不用意にバージョンあげると互換性は結構壊れてるかも
  • デフォルトのバックエンドは PostgreSQL
    • MySQL や SQLite も使えます。実用性はわからないけど、Redis のバックエンドなんかもあります
  • PostgreSQL の結構新しめの機能を使っている
    • SKIP LOCKED とか使っています
    • 排他制御をいい感じにやりつつ、ジョブが遊ばないような工夫がされています
  • 依存モジュールが結構シビア
    • SQL::Abstract, DBD::Pg あたりが既存環境だと辛いかも
  • 後発なので、便利機能色々
    • 優先度のサポート
    • 管理系の API を持っている
  • etc.

と言った感じです

使ってみよう

まず、DB を用意します。近年であれば、docker でやるのが楽ですかね(開発環境にすでにあるなら、それを使いましょう。ただし Minion は PostgreSQL 9.5以上を要求するので注意)

docker run -d --name postgres96 -p 5432:5432 postgres:9.6
createdb -h localhost -U postgres test

必要なモジュールをインストールしましょう

cpanm Minion Mojo::Pg

雑な動作サンプルはこんな感じです。

#!/usr/bin/perl
use strict;
use warnings;
use Minion;
use feature 'say';

my $minion = Minion->new(Pg => 'postgresql://postgres@localhost/test');

# ワーカーの定義
$minion->add_task( tashizan => sub {
    my ($job, @args) = @_;
    say $args[0] + $args[1];
});

# エンキュー
$minion->enqueue(tashizan => [1, 2]);
$minion->enqueue(tashizan => [100, 200]);

# ワーカーの起動
my $worker = $minion->worker;
$worker->run;

実行するとこんな感じ。

perl worker.pl 
3
300

ワーカーが動きっぱなしになるので、Ctrl-c で抜けましょう。

実際に使うときは、ワーカー、エンキュー側でファイルを分けて、いい感じにクラス設計して使ってくださいね。

もうちょっと細かい話も書きたかったですが、分量と時間的に(僕が)厳しくなってきたので、続きはいつかどこかで。

あと、事例としては、僕の Kichijoji.pm の話辺りを参考にしていただければ、と思います。

明日はskaji さんの Mouse と Xslate の話みたいです。これは楽しみだ。

ではでは。