TheSchwartz で時間が掛かる job を実行するときは grab_for に注意

TheSchwartz の worker で、一つの job が worker->grab_for (default 3600) 秒以上掛かる処理をすると、処理中の job を他の worker が掴んでしまう。

具体的には大量のメール送信をしていたんだけど、Data::Valve でスロットリングしてゆっくり送っていたら 1時間以上掛かって、別の worker も同じ job を実行してしまった。結果、同じメールが 2通ずつ出た orz

grab_for は job を処理しはじめた worker が、失敗を報告もできないでクラッシュした場合に、別の worker が処理できるようにするもの。しかし送信してしまったメールは取り消せないからな……

package MyWorker;
use base qw/ TheSchwartz::Worker /;

sub grab_for { 60 * 60 * 24 * 365 * 10 } # しかし10年後に実行されても困る

max_retries { 0 } でも、grab_for 秒以後の処理は実行されちゃう。

あとから実行されても嬉しくない job は、grab_for に関わらず未来永劫実行しないでほしいのだけど。一つの job があんまり長時間にならないように、job 自体を分割するべきかな。