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