Railsの非同期処理実行を実現するgemとして,sidekiqは非常に有用です.
有名ではあるので,一般的な使い方についてはここでは説明しません.
この辺を見ると簡単に使えるようになると思います.
リトライについて
sidekiqに任せる処理に,エラーを含むような処理を実装すると,エラーにより処理が中断された後,sidekiqが自動でリトライをしてくれます.
ただ,そのリトライ回数は,無限ではありません.
デフォルトの設定のまま
class TestWorker include Sidekiq::Worker def perform(*args) raise end end
こんな処理を書いておくと,sidekiqは25回までリトライをしてくれます.
しかし26回目はなく,その後DeadJob(死亡)に振り分けられ,以降リトライされなくなります.
この死亡タスクは,sidekiqのダッシュボードからのみ再試行をかけることができます.
公式のwikiによると,このリトライ回数25回が多すぎる場合は,開発者がリトライ回数を指定できるとあります.
Error Handling · mperham/sidekiq Wiki · GitHub
class TestWorker include Sidekiq::Worker sidekiq_options :retry => 5 def perform(*args) raise end end
こうすると,5回リトライした後,DeadJobに振り分けられます.
リトライ回数に26回以上を指定することができるのか?
というわけでやってみました.
class TestWorker include Sidekiq::Worker sidekiq_options :retry => 30 def perform(*args) raise end end
なんと無事30回のリトライを実行した後,DeadJobに入りました.
これって上限とか特に定めていないんでしょうか.
どこまでリトライしてくれるのかはわからないですが,結構言いなりでやってくれそうな予感がします.
リトライ間隔について
上記のテスト,このまま実行するとリトライの間隔がどんどん伸びていきます.
これは,sidekiqがリトライの間隔を自動調節しているために,回数が増えるごとに間隔が伸びていくのです.
公式のwikiによると,
[sec]
という式に基づいてリトライ間隔を計算します.
このリトライ間隔はsidekiq_retry_in
で指定することができます.
今回の例でいうなら,全部等間隔で実行してほしいので,
class TestWorker include Sidekiq::Worker sidekiq_options :retry => 30 sidekiq_retry_in do |count| 10 end def perform(*args) raise end end
こんな感じで10秒固定としました.
DeadJobについて
指定回数以降,DeadJobに入れてほしくない場合は,sidekiq_options
に:dead => false
を渡します.
class TestWorker include Sidekiq::Worker sidekiq_options :retry => 30, :dead => false ## 中略 end
この場合,DeadJobのキューに入ることなく,そのまま処理失敗に入り,再試行はできなくなります.
また,DeadJobに入るタイミングで何か処理をしたいときは,sidekiq_retries_exhausted
を定義します.
class TestWorker include Sidekiq::Worker sidekiq_retries_exhausted do |msg| Sidekiq.logger.warn "Failed #{msg['class']} with #{msg['args']}: #{msg['error_message']}" end ## 中略 end
この処理はDeadJobに入る直前で呼び出されます.