Closed5

sidekiqを眺めていたらFloatDomainError: -Infinityエラーが出ていたので調査

Matsukura YukiMatsukura Yuki

ググってもこちらの記載しか出てこない。
https://github.com/sidekiq/sidekiq/issues/4870

アプリケーションレベルでは、このエラーが出るようなコードを書いていないのでSidekiq内部で起きているエラーっぽいがスタックトレースが出ないのでどこで出ているかわからない。。。

Matsukura YukiMatsukura Yuki

よくよく観察していると、jobが1回目の失敗のときにはFloatDomainErrorが出ている。
2回目以降は出てない。

感で探ってみて、おそらく以下の返り値がFloatになっていたのが問題で、sidekiq側での比較でFloatを予期していなかった気がする。

   sidekiq_retry_in do |count|
-    (Math.log(count) * 10) + 1
+    ((Math.log(count) * 10) + 1).round
   end

しかし、上記のブロックを呼び出しているコードを見ると、Floatで返却してもintに変換されている。。。
https://github.com/sidekiq/sidekiq/blob/main/lib/sidekiq/job_retry.rb#L219C26-L220C1

ので、違う。

Matsukura YukiMatsukura Yuki

原因がわかった。
sidekiq_retry_in には0が入ってくるらしい。

 sidekiq_retry_in do |count|
   ((Math.log(count) * 10) + (rand * 5) + 1).round
 end

という感じのコードを書いていたから問題なんだ。
retryなのに、0から始まるのって適切な用語ではない気がするが。。。

とりあえず以下のように変更して対処しました。

 sidekiq_retry_in do |count|
  return 0 if count == 0
   ((Math.log(count) * 10) + (rand * 5) + 1).round
 end
Matsukura YukiMatsukura Yuki

if文はカッコ悪いので以下のようにリファクタしました。

 sidekiq_retry_in do |count|
   Math.log(10) * count + (rand * 5) * count
 end

0のときは0が返ってきて欲しいというのもあり。。


Matsukura YukiMatsukura Yuki

そもそも何で対数的にしたいかと言うと、何回もすぐにリトライしたいから。。。。
非同期で行っているjobが不安定なのである程度短めにリトライしたいため。

このスクラップは4ヶ月前にクローズされました