Retry failed blocks with jittered backoff
Ruby
# Retry a block on transient errors with exponential backoff plus jitter.
def with_retries(attempts: 4, base: 0.1, rescues: [StandardError])
attempt = 1
begin
yield
rescue *rescues => error
raise if attempt >= attempts
warn "attempt #{attempt} failed: #{error.message}"
delay = base * (2**(attempt - 1))
sleep(delay * (0.5 + rand / 2.0))
attempt += 1
retry
end
end
calls = 0
result = with_retries(attempts: 3, base: 0.01) do
calls += 1
raise IOError, 'temporary failure' if calls < 3
"finished after #{calls} attempt(s)"
end
puts result