理系学生日記

おまえはいつまで学生気分なのか

Gearman::Task の uniq オプション

Gearman::Task の第三引数の hashref ではコールバックが指定できるが、uniq というオプションも指定することができる。この uniq キーに対する value は、ユニークキーを指定することができ、ユニークキーが一致するジョブは merge される。つまり、一度に何個入れようと、一回しか実行されない。

というわけで、通常このオプションを指定するときは自身でユニークキーを生成してやる必要がある。Java でいう hashCode みたいなものだと思うと分かりやすい。
ただ、単純なデータで一々ユニークキーを生成するのがメンドくさい場合は、'-' を指定すると幸せになれるようだ。'-' を指定すると、Worker 側に渡す arg (Gearman::Task コンストラクタの第 2 引数) の値を使って自動的に uniq になるかどうかを判断してくれる。

実際に、以下のようなコードを書いてみる。gearman-client 側では { hoge => 1, fuga => 2 } という hashref で 1 回、{ foo => 3 } という hashref で 2 回 dispatch_background を実行する。しかし、gearman-worker では、それぞれの hashref に対し 1 度しかタスクを実行していない。

gearman-client.pl

use strict;
use warnings;
use Gearman::Client;
use Storable 'freeze';

my $client = Gearman::Client->new( job_servers => [ qw/127.0.0.1:4730/ ] );

my $freezed = freeze({ hoge => 1, fuga => 2 });
$client->dispatch_background( 
    Gearman::Task->new('dump', \$freezed, { uniq => '-' }) 
);

$freezed = freeze({ foo => 3 });
$client->dispatch_background( 
    Gearman::Task->new('dump', \$freezed, { uniq => '-' }) 
);

$client->dispatch_background( 
    Gearman::Task->new('dump', \$freezed, { uniq => '-' }) 
);

gearman-worker.pl

use strict;
use warnings;
use Gearman::Worker;
use Storable 'thaw';
use YAML 'Dump';

my $worker = Gearman::Worker->new;
$worker->job_servers('127.0.0.1:4730');
$worker->register_function(dump => sub {
     my $arg = thaw( shift()->arg );
     print "dump start\n";
     sleep 3;
     print Dump $arg;
});
$worker->work while 1;

実行結果

$ ./gearman-worker.pl
dump start
---
fuga: 2
hoge: 1
dump start
---
foo: 3