Documentation
¶
Overview ¶
Package backoff provides various backoff strategies for retry mechanisms.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Constant ¶
type Constant struct {
// contains filtered or unexported fields
}
Constant implements a constant backoff strategy with fixed delay intervals. This strategy returns the same delay duration for each retry attempt.
Use Constant for scenarios where you want predictable, uniform delays between retry attempts. This is useful when you need consistent timing or when working with systems that have specific rate limiting requirements.
func NewConstant ¶
NewConstant creates a new constant backoff strategy with the specified interval.
Parameters:
- d: The fixed delay duration between retry attempts
- opts: Optional configuration functions (WithMaxRetries, WithMaxElapsed, etc.)
Example:
// 500ms delay with max 3 retries constant := NewConstant(500*time.Millisecond, WithMaxRetries(3)) // 1 second delay with 30 second total timeout constant := NewConstant(time.Second, WithMaxElapsed(30*time.Second))
func (*Constant) Next ¶
Next returns the next delay duration and whether more retries are allowed. For constant backoff, this always returns the same interval duration until maximum retry or elapsed time limits are reached.
Returns:
- time.Duration: The delay duration (always the configured interval)
- bool: true if more retries are allowed, false if limits are reached
type Decorrelated ¶
type Decorrelated struct {
// contains filtered or unexported fields
}
Decorrelated implements a decorrelated jitter backoff strategy. This strategy uses randomized delays to prevent synchronized retry attempts across multiple clients, effectively preventing thundering herd problems.
The algorithm picks a random delay between the minimum interval and (previous_delay * factor), providing both exponential growth characteristics and randomization to spread out retry attempts.
func NewDecorrelated ¶
func NewDecorrelated(initial time.Duration, factor float64, opts ...Option) *Decorrelated
NewDecorrelated creates a new decorrelated jitter backoff strategy.
Parameters:
- initial: The initial delay duration for the first retry
- factor: The growth factor for delay calculation (must be > 1.0)
- opts: Optional configuration functions
If factor <= 1.0, it defaults to 3.0 for effective jitter spread. If no maxInterval is specified, it defaults to 30 seconds.
Example:
// Start at 100ms with 3x growth factor dcr := NewDecorrelated(100*time.Millisecond, 3.0, WithMaxInterval(10*time.Second), WithMaxRetries(5)) // With custom min/max bounds dcr := NewDecorrelated(50*time.Millisecond, 2.5, WithMinInterval(10*time.Millisecond), WithMaxInterval(5*time.Second))
func (*Decorrelated) Next ¶
func (dcr *Decorrelated) Next() (time.Duration, bool)
Next returns the next decorrelated delay duration. For the first retry, returns the initial duration. For subsequent retries, picks a random duration between minInterval and (previous_delay * factor), bounded by maxInterval.
This randomization helps prevent multiple clients from retrying simultaneously, reducing load spikes on recovering systems.
Returns:
- time.Duration: The calculated random delay duration
- bool: true if more retries are allowed, false if limits are reached
func (*Decorrelated) Reset ¶
func (dcr *Decorrelated) Reset()
Reset resets the decorrelated backoff to its initial state. This clears the retry count, elapsed time, and previous delay history.
type EqualJitter ¶
type EqualJitter struct{}
EqualJitter implements a jitter strategy that uses half the calculated delay as a base and adds randomness to the other half. This provides a good balance between maintaining reasonable delay lengths and adding randomization.
Formula: (calculated_delay / 2) + random(0, calculated_delay / 2)
type Exponential ¶
type Exponential struct {
// contains filtered or unexported fields
}
Exponential implements an exponential backoff strategy where delays increase exponentially with each retry attempt.
This strategy is effective for handling temporary failures and avoiding overwhelming systems during recovery periods.
func NewExponential ¶
func NewExponential(base time.Duration, factor float64, opts ...Option) *Exponential
NewExponential creates a new exponential backoff strategy.
Parameters:
- base: The initial delay duration for the first retry
- factor: The multiplier applied to increase delays (must be > 1.0)
- opts: Optional configuration functions
If factor <= 1.0, it defaults to 2.0 for proper exponential growth.
Example:
// Start at 100ms, double each time, max 5 seconds exp := NewExponential(100*time.Millisecond, 2.0, WithMaxInterval(5*time.Second)) // With jitter to prevent thundering herd exp := NewExponential(50*time.Millisecond, 1.5, WithJitter(), WithMaxRetries(10))
func (*Exponential) Next ¶
func (e *Exponential) Next() (time.Duration, bool)
Next returns the next exponentially increased delay duration. The delay grows exponentially: base, base*factor, base*factor^2, etc.
The calculated delay is subject to:
- Jitter application (if configured)
- Min/max interval bounds
- Overflow protection (capped at math.MaxInt64)
Returns:
- time.Duration: The calculated delay duration
- bool: true if more retries are allowed, false if limits are reached
func (*Exponential) Reset ¶
func (e *Exponential) Reset()
Reset resets the exponential backoff to its initial state. This clears the retry count, elapsed time, and current delay calculation.
type FullJitter ¶
type FullJitter struct{}
FullJitter implements a jitter strategy that randomizes the entire delay. The final delay is a random value between 1 and the calculated delay duration. This provides maximum randomization but may result in very short delays.
Formula: random(1, calculated_delay)
type Jitter ¶
type Jitter interface {
// Apply takes a calculated delay duration and applies jitter using the
// provided random number generator, returning the final delay to use.
Apply(d time.Duration, r *rand.Rand) time.Duration
}
Jitter defines the interface for applying randomization to delay durations. Jitter strategies help prevent thundering herd problems by adding randomness to retry attempts, spreading them out over time instead of having all clients retry simultaneously.
type NoneJitter ¶
type NoneJitter struct{}
NoneJitter implements a jitter strategy that applies no randomization. The delay duration is returned unchanged. This is the default jitter strategy when no jitter options are specified.
type Option ¶
type Option func(*options)
Option is a function type used to configure backoff strategies. Options are applied during the creation of backoff instances to customize behavior such as retry limits, jitter, and timing bounds.
func WithJitter ¶
func WithJitter() Option
WithJitter enables equal jitter for the backoff strategy. Equal jitter adds randomness to delay intervals by using half the calculated delay plus a random amount up to the other half. This helps prevent thundering herd problems.
Example:
backoff := NewExponential(100*time.Millisecond, 2.0, WithJitter()) // Uses EqualJitter strategy
func WithJitterStrategy ¶
WithJitterStrategy sets a custom jitter strategy for the backoff. This allows you to use FullJitter, EqualJitter, NoneJitter, or implement your own custom jitter algorithm.
Example:
backoff := NewExponential(100*time.Millisecond, 2.0,
WithJitterStrategy(&FullJitter{}))
func WithMaxElapsed ¶
WithMaxElapsed sets the maximum total elapsed time for all retry attempts. Once this duration has passed, Next() will return (0, false). A value of 0 means no time limit.
Example:
backoff := NewExponential(100*time.Millisecond, 2.0, WithMaxElapsed(30*time.Second)) // Stop after 30 seconds total
func WithMaxInterval ¶
WithMaxInterval sets the maximum delay interval for backoff strategies. Delays will be capped at this duration regardless of the backoff algorithm. A value of 0 means no maximum limit.
Example:
backoff := NewExponential(100*time.Millisecond, 2.0, WithMaxInterval(5*time.Second))
func WithMaxRetries ¶
WithMaxRetries sets the maximum number of retry attempts. After this many retries, Next() will return (0, false). A value of -1 means unlimited retries.
Example:
backoff := NewConstant(100*time.Millisecond, WithMaxRetries(5)) // Stop after 5 attempts
func WithMinInterval ¶
WithMinInterval sets the minimum delay interval for backoff strategies. Delays will never be shorter than this duration. A value of 0 means no minimum limit.
Example:
backoff := NewExponential(10*time.Millisecond, 2.0, WithMinInterval(50*time.Millisecond))
func WithRandSource ¶
WithRandSource sets a custom random source for jitter calculations. This allows for deterministic testing or custom randomization behavior. If not specified, a default PCG source with fixed seed is used.
Example:
source := rand.NewPCG(42, 1024) backoff := NewExponential(100*time.Millisecond, 2.0, WithRandSource(source), WithJitter())
type Sequence ¶
type Sequence interface {
// Next returns the next delay duration and a boolean indicating
// whether more retries are allowed. Returns (0, false) when
// maximum retries or elapsed time limits are reached.
Next() (time.Duration, bool)
// Reset resets the backoff sequence to its initial state,
// clearing retry count and elapsed time.
Reset()
}
Sequence defines the interface for backoff strategies. Implementations should provide methods to get the next delay duration and reset the internal state.