TheSchwartzで仕事をあとにまわす

web2.0 時代のジョブキューサーバー Gearman と TheSchwartz の関係について - TokuLog 改めB日記に書かれているとおり、Gearmanは仕事を投げられたらすぐやって返す前提になっていて今やりたくないけどあとでやるみたいなのができません。

たとえば、10分後にならできるんだけど、という仕事が来たとします。
このときGearmanのワーカの中でsleepして10分待つと、後から来たほかの仕事を一切しないで10分待つことになってしまって、後から来た仕事が今すぐできるものだったとしても10分待たれさるのでGearmanだと今来た仕事のためにsleepして待つわけにはいきません。

結果としてGearmanだとやってきた仕事を今すぐやるか、絶対やらないか、の二択になってしまいます。


それだと困るので、もう一方のTheSchwartzだと、今やりたくないけどあとでやる、ことができるのかなーと思って調べてみたらできました。GearmanとくらべてTheSchwartzのほうはどうやって使うかあまり書かれてなかったので、TheSchwartzを使ってやってきた仕事を後に回す方法を書きます。

MySQLにテーブルを作る

Gearmanが仕事のキューをメモリ上に持つのに対して、TheSchwartzはデータベースに保存します。だからはじめにデータベースにテーブル作ったりするんだろうなと思ったのですがTheSchwartz - reliable job queue - search.cpan.orgにもTheSchwartz をためす - TokuLog 改めB日記にもテーブルを作ることについて触れられていません。

なければ勝手に作ってくれるのかなと思ってSYNOPSISのコードを実行してみたけどやっぱり自動でできたりはしなそうだったので調べたらCatalyst and TheSchwartz: Reliable JobQueue in a great framework - Voxにschema.sqlを使うといいと書いてありました。このスキーマをmysqlで実行すればTheSchwartzのキューを管理するためのテーブルが出来上がります。

コード

セットアップができれば後はGearmanとおなじかんじです。workerで仕事の名前を登録して、仕事を待ちます。 Gearmanとちがうところは、関数を登録するのではなくTheSchwartz::Workerのサブクラスを作って、そのクラス名を登録するところ。仕事が来た時には作ったサブクラスのworkメソッドが呼び出されます。

TheSchwartzのサーバは、デフォルトでは5秒間隔でキューをチェックして、仕事があった時にはその仕事の名前に応じたワーカを起動します。workはふられた仕事に対してWORKINGにある4つのメソッドのうちのどれかを呼び出して終了します。

completed()
仕事を問題なくこなした時に呼び出します。TheSchwartzでは問題なく終わった時は、その結果をどこかに保存したりはできないようで、なにも引数はありません。そういうときはわざとfailしたことにするのかな。
failed($msg, $exit_status)

やったけどだめだったときに呼び出します。failedを呼ぶと、失敗した時刻、ジョブのID, $msg, $exit_statusがdbのerrorテーブルとexitstatusテーブルに記録されます。perlの実行時エラーでなどで失敗した時も同様にerrorテーブルに記録されるようになっています。

max_retriesが0以上に設定されている時はfailedを呼んでもジョブはキューから削除されずに、max_retriesの値に達するまで即時再度実行されるようになっています。常に失敗するような状態になっている時にmax_retriesが大きな値になっているとすごい勢いでループしてCPUを浪費するので注意が必要です。

permanent_failure( $msg, $exit_status )
リトライしてもだめなエラーの時にはpermanent_failureを呼び出すとmax_retriesに関わらずリトライされません。$exit_status = 1で呼び出すとさらにキューからジョブを削除されます。
replace_with
今のジョブをキューから削除してほかのジョブで置き換えたい時に呼び出します。 たとえば、ログインしないとアクセスできないページのデータを読み込みたい時、持っているクッキーがまだ有効だと思ってアクセスしたらクッキーが無効でログインが必要になった場合、ページを読み込むといういまのジョブを
  1. ログインページにアクセス
  2. アカウント情報をpost
  3. データを読み込みたいページにアクセス
という3つのジョブと入れ替えたい、というような時に使います。

今回はこの最後のreplace_withを使って今きた仕事を明日(24時間後)にするサンプルを作りました。
TheSchwartzには時間を指定してジョブを実行させることができるようになっていたりして、やってきた仕事を今すぐやるかやらないかしかないGearmanにくらべて柔軟な管理ができます。

Gearmanに比べるとスペルが覚えられないのとタイプしにくいのが難点です。

worker.pl

package MyWorker;
use base qw( TheSchwartz::Worker );

sub work {
    my ($class, $job) = @_;

    my $deferredJob = TheSchwartz::Job->new(
        funcname => $job->funcname,
        arg => $job->arg,
        run_after => time + 24 * 3600
    );

    $job->replace_with( $deferredJob );
}

package main;
use TheSchwartz;

my $client = TheSchwartz->new(
    databases => [{dsn => 'dbi:mysql:the_schwartz', user => 'root', pass => ''}],
    verbose => 1
);
$client->can_do('MyWorker');
$client->work();

client.pl

use TheSchwartz;
use JSON;

my $client = TheSchwartz->new(
    databases => [{dsn => 'dbi:mysql:the_schwartz', user => 'root', pass => ''}],
    verbose => 1
);

my $arg = {
    hello => "world",
    fizz => "buzz",
};
$client->insert('MyWorker' => to_json($arg) );

tags

  • perl
  • 「TheSchwartzで仕事をあとにまわす」のはてなブックマーク数
  • 「TheSchwartzで仕事をあとにまわす」deliciousブックマーク数
  • 「TheSchwartzで仕事をあとにまわす」をはてなブックマークに追加
  • save "TheSchwartzで仕事をあとにまわす" to del.icio.us
  • 「TheSchwartzで仕事をあとにまわす」をリアルタイムブログ検索
  • permalink
  • サービスのread/writeとコンテンツのfav
  • クローンサービスのAPIデザイン

comments

TypeKey Enabled
スタイル用のHTMLタグが使えます。
*required

trackbacks

トラックバック元エントリにこのエントリへのリンクがない場合はトラックバックを受け付けません。

http://labs.gmo.jp/mt/mt-tb.cgi/222
©2010 Kentaro Kumagai, GMO Internet Labs., GMO Internet, inc.
bits and bytes
2008 .06. 25 18:38

tagcloud

  • API3
  • C/C++2
  • E4X1
  • FUSE2
  • Firefox28
  • HTML4
  • IE1
  • MySQL1
  • OSX4
  • Opera2
  • PHP4
  • UI2
  • WebKit1
  • XML1
  • XPCOM4
  • XPath4
  • apache2
  • binary2
  • book1
  • data13
  • debug5
  • design2
  • experiments4
  • extension14
  • geo1
  • google gears2
  • google maps API1
  • greasemonkey4
  • httpd5
  • javascript22
  • linux1
  • logging2
  • mobile4
  • perl6
  • tips6
  • tool11
  • vim2
  • visualization3
  • widget1
  • wii3
  • windows7
  • サービス7
  • 和訳1

Archives

  • 2008.07 (1)
  • 2008.06 (4)
  • 2008.05 (5)
  • 2008.04 (4)
  • 2008.03 (4)
  • 2008.02 (6)
  • 2008.01 (3)
  • 2007.12 (4)
  • 2007.11 (5)
  • 2007.10 (4)
  • 2007.09 (4)
  • 2007.08 (4)
  • 2007.07 (8)
  • 2007.06 (7)
  • 2007.05 (4)
  • 2007.04 (5)
  • 2007.03 (6)
  • 2007.02 (4)
  • 2007.01 (6)

about

  • bits and bytesのXML
  • 「bits and bytes」のCreative Commons
  • Powered by Movable Type
  • イベントと地図 - モグ
  • Use ecto to blog!
  • bits and bytesのはてなブックマーク数
  • bits and bytesをMy Yahoo!に追加
  • Subscribe with Bloglines