Class: Tenax::Retry::Backoff::Exponential

Inherits:
Strategy
  • Object
show all
Defined in:
lib/tenax/retry/backoff/exponential.rb

Overview

Exponential backoff without jitter.

delay = min(cap, base * factor ** (attempt - 1))

Note: pure exponential backoff (no jitter) is generally NOT recommended for production use against shared remote services, because all clients retry at synchronized intervals after a shared failure — producing a "thundering herd" load pattern. Prefer DecorrelatedJitter unless you specifically need deterministic delays.

Examples:

backoff = Tenax::Retry::Backoff::Exponential.new(base: 0.5, cap: 30)
backoff.delay_for(1) # => 0.5
backoff.delay_for(2) # => 1.0
backoff.delay_for(3) # => 2.0
backoff.delay_for(7) # => 30.0   (capped)

Instance Method Summary collapse

Constructor Details

#initialize(base:, cap:, factor: DEFAULT_FACTOR) ⇒ Exponential

Returns a new instance of Exponential.

Parameters:

  • base (Numeric) —

    initial delay in seconds; positive

  • cap (Numeric) —

    maximum delay in seconds; positive

  • factor (Numeric) (defaults to: DEFAULT_FACTOR) —

    growth multiplier per attempt (default 2.0)

Raises:

  • (ArgumentError) —

    on invalid configuration



33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/tenax/retry/backoff/exponential.rb', line 33

def initialize(base:, cap:, factor: DEFAULT_FACTOR)
  raise ArgumentError, "base must be positive, got #{base}"     if base <= 0
  raise ArgumentError, "cap must be positive, got #{cap}"       if cap <= 0
  raise ArgumentError, "factor must be > 1, got #{factor}"      if factor <= 1
  raise ArgumentError, "cap must be >= base, got base=#{base}, cap=#{cap}" if cap < base

  super()
  @base   = base.to_f
  @cap    = cap.to_f
  @factor = factor.to_f
  freeze
end

Instance Method Details

#delay_for(attempt) ⇒ Float

Returns delay seconds (capped).

Parameters:

  • attempt (Integer) —

    1-based attempt number

Returns:

  • (Float) —

    delay seconds (capped)

Raises:

  • (ArgumentError)


48
49
50
51
52
53
# File 'lib/tenax/retry/backoff/exponential.rb', line 48

def delay_for(attempt)
  raise ArgumentError, "attempt must be >= 1, got #{attempt}" if attempt < 1

  delay = @base * (@factor**(attempt - 1))
  [delay, @cap].min
end