こいつ(CakeResque)を使っているときに調べたメモ。
Workerでエラーが発生したとき
Workerでエラーが発生した際に、ジョブキューの中身はどうなるんだ?消えてしまうん?という調べ物が発生したので、少し調べた。
つまり、Workerでエラーが発生してジョブを完遂できなかった際に、ジョブキューの中身が残っていれば、エラー復旧後にそのままWorkerによろしくやってもらうことができるよね!と、いうことです。
Workerがジョブキューの中身を取り出す動き
redisのCLIを起動して、monitorコマンドを使って、redis上で実行されるコマンドを観察してみたところ、、、
1469018495.522819 [0 127.0.0.1:49197] "LPOP" "resque:queue:cakeresque_001"
LPOPでジョブキューの中身を取り出しているよぅぅぅなので、Workerがジョブキューの中身を取り出した時点で、削除されてしまっている。
例えば以下の様な、エラーを起こしてfalseをリターンしているという程のソースを用意して、CakeResqueをスタートさせておくと、Worker側はエラーで処理が終了しているのに、ジョブ自体は実行されてredisのキューから消えてしまい、エラー復旧後にキューがない、と、いうことになる。
<?php
App::uses('AppShell', 'Console/Command');
class TestjobShell extends AppShell {
public function testAction() {
return false;
}
}
とりあえずの解決策
エラー時の処理の中で、もう一度ジョブキューを登録する処理を入れることで、キューが失われなくなる。つまり、LPOPでキューの先頭から取り出した要素を、キューの最後尾に戻してあげる形になる。
多分もっとよい解決策があるんだろうけど、とりあえずはこんな感じでいけそう。
<?php
App::uses('AppShell', 'Console/Command');
class TestjobShell extends AppShell {
public function testAction() {
try {
if ($hogehoge === true) {
return true;
} else {
throw new Exception('ERROR!!!');
}
} catch (Exception $e) {
// 失敗したジョブはキューとしてまた登録する
CakeResque::enqueue('cakeresque_001', get_class($this), array(__FUNCTION__,$this->args[0], $this->args[1]));
return false;
}
}
}