sidekiqのリトライ回数は26回以上を指定できる

Railsの非同期処理実行を実現するgemとして,sidekiqは非常に有用です.
有名ではあるので,一般的な使い方についてはここでは説明しません.


Rails - sidekiqの使い方 - Qiita


この辺を見ると簡単に使えるようになると思います.


リトライについて

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によると,
(RetryCount^4) + 15 + (rand(30) \times (RetryCount + 1)) [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に入る直前で呼び出されます.



参考


Error Handling · mperham/sidekiq Wiki · GitHub