地方エンジニアの学習日記

興味ある技術の雑なメモだったりを書いてくブログ。たまに日記とガジェット紹介。

【Ruby】Jitter付きリトライ

github.com

require 'timeout'
require 'securerandom'

def retry_with_jitter(max_retries: 5, initial_delay: 1, multiplier: 2, jitter_factor: 0.5)
  retries = 0
  begin
    yield
  rescue => e
    retries += 1
    if retries > max_retries
      raise # リトライ回数上限を超えた場合は例外を再raise
    end

    delay = initial_delay * (multiplier ** (retries - 1))
    # ランダムなjitterをdelayに加える
    jitter = delay * jitter_factor * (2 * SecureRandom.random_number - 1) # [-delay * jitter_factor, delay * jitter_factor] の範囲
    sleep_time = [0, delay + jitter].max # 負のsleep時間を避ける

    puts "リトライ #{retries}: #{e.class} - #{e.message}#{sleep_time.round(2)}秒後に再試行します..."
    sleep sleep_time
    retry
  end
end

retry_with_jitter do
  puts "処理を実行中..."
  if rand < 0.7
    raise "一時的なエラーが発生しました!"
  end
  puts "処理が成功しました。"
end