Documentation ¶
Overview ¶
Package backoff implements backoff algorithms for retrying operations.
Also has a Retry() helper for retrying operations that may fail.
Index ¶
Constants ¶
const ( DefaultInitialInterval = 500 * time.Millisecond DefaultRandomizationFactor = 0.5 DefaultMultiplier = 1.5 DefaultMaxInterval = 60 * time.Second DefaultMaxElapsedTime = 15 * time.Minute )
Default values for ExponentialBackOff.
const Stop time.Duration = -1
Indicates that no more retries should be made for use in NextBackOff().
Variables ¶
var SystemClock = systemClock{}
SystemClock implements Clock interface that uses time.Now().
Functions ¶
func Retry ¶
Retry the function f until it does not return error or BackOff stops. f is guaranteed to be run at least once. It is the caller's responsibility to reset b after Retry returns.
Retry sleeps the goroutine for the duration returned by BackOff after a failed operation returns.
Usage:
operation := func() error { // An operation that may fail } err := backoff.Retry(operation, backoff.NewExponentialBackOff()) if err != nil { // Operation has failed. } // Operation is successfull.
Types ¶
type BackOff ¶
type BackOff interface { // Gets the duration to wait before retrying the operation or // backoff.Stop to indicate that no retries should be made. // // Example usage: // // duration := backoff.NextBackOff(); // if (duration == backoff.Stop) { // // do not retry operation // } else { // // sleep for duration and retry operation // } // NextBackOff() time.Duration // Reset to initial state. Reset() }
Back-off policy when retrying an operation.
type ConstantBackOff ¶
func NewConstantBackOff ¶
func NewConstantBackOff(d time.Duration) *ConstantBackOff
func (*ConstantBackOff) NextBackOff ¶
func (b *ConstantBackOff) NextBackOff() time.Duration
func (*ConstantBackOff) Reset ¶
func (b *ConstantBackOff) Reset()
type ExponentialBackOff ¶
type ExponentialBackOff struct { InitialInterval time.Duration RandomizationFactor float64 Multiplier float64 MaxInterval time.Duration // After MaxElapsedTime the ExponentialBackOff stops. // It never stops if MaxElapsedTime == 0. MaxElapsedTime time.Duration Clock Clock // contains filtered or unexported fields }
ExponentialBackOff is an implementation of BackOff that increases the back off period for each retry attempt using a randomization function that grows exponentially.
NextBackOff() is calculated using the following formula:
randomized_interval = retry_interval * (random value in range [1 - randomization_factor, 1 + randomization_factor])
In other words NextBackOff() will range between the randomization factor percentage below and above the retry interval. For example, using 2 seconds as the base retry interval and 0.5 as the randomization factor, the actual back off period used in the next retry attempt will be between 1 and 3 seconds.
Note: max_interval caps the retry_interval and not the randomized_interval.
If the time elapsed since an ExponentialBackOff instance is created goes past the max_elapsed_time then the method NextBackOff() starts returning backoff.Stop. The elapsed time can be reset by calling Reset().
Example: The default retry_interval is .5 seconds, default randomization_factor is 0.5, default multiplier is 1.5 and the default max_interval is 1 minute. For 10 tries the sequence will be (values in seconds) and assuming we go over the max_elapsed_time on the 10th try:
request# retry_interval randomized_interval 1 0.5 [0.25, 0.75] 2 0.75 [0.375, 1.125] 3 1.125 [0.562, 1.687] 4 1.687 [0.8435, 2.53] 5 2.53 [1.265, 3.795] 6 3.795 [1.897, 5.692] 7 5.692 [2.846, 8.538] 8 8.538 [4.269, 12.807] 9 12.807 [6.403, 19.210] 10 19.210 backoff.Stop
Implementation is not thread-safe.
func NewExponentialBackOff ¶
func NewExponentialBackOff() *ExponentialBackOff
NewExponentialBackOff creates an instance of ExponentialBackOff using default values.
func (*ExponentialBackOff) GetElapsedTime ¶
func (b *ExponentialBackOff) GetElapsedTime() time.Duration
GetElapsedTime returns the elapsed time since an ExponentialBackOff instance is created and is reset when Reset() is called.
The elapsed time is computed using time.Now().UnixNano().
func (*ExponentialBackOff) NextBackOff ¶
func (b *ExponentialBackOff) NextBackOff() time.Duration
NextBackOff calculates the next back off interval using the formula:
randomized_interval = retry_interval +/- (randomization_factor * retry_interval)
func (*ExponentialBackOff) Reset ¶
func (b *ExponentialBackOff) Reset()
Reset the interval back to the initial retry interval and restarts the timer.
type StopBackOff ¶
type StopBackOff struct{}
StopBackOff is a fixed back-off policy that always returns backoff.Stop for NextBackOff(), meaning that the operation should not be retried.
func (*StopBackOff) NextBackOff ¶
func (b *StopBackOff) NextBackOff() time.Duration
func (*StopBackOff) Reset ¶
func (b *StopBackOff) Reset()
type Ticker ¶
Ticker holds a channel that delivers `ticks' of a clock at times reported by a BackOff.
Ticks will continue to arrive when the previous operation is still running, so operations that take a while to fail could run in quick succession.
Usage:
operation := func() error { // An operation that may fail } b := backoff.NewExponentialBackOff() ticker := backoff.NewTicker(b) var err error for _ = range ticker.C { if err = operation(); err != nil { log.Println(err, "will retry...") continue } ticker.Stop() break } if err != nil { // Operation has failed. } // Operation is successfull.
type ZeroBackOff ¶
type ZeroBackOff struct{}
ZeroBackOff is a fixed back-off policy whose back-off time is always zero, meaning that the operation is retried immediately without waiting.
func (*ZeroBackOff) NextBackOff ¶
func (b *ZeroBackOff) NextBackOff() time.Duration
func (*ZeroBackOff) Reset ¶
func (b *ZeroBackOff) Reset()