backoff

package module
v0.0.0-...-e46b80a Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 20, 2024 License: BSD-2-Clause Imports: 7 Imported by: 57

README

backoff

Go implementation of "Exponential Backoff And Jitter"

This package implements the backoff strategy described in the AWS Architecture Blog article "Exponential Backoff And Jitter". Essentially, the backoff has an interval time.Duration; the nth call to backoff will return an a time.Duration that is 2 n * interval. If jitter is enabled (which is the default behaviour), the duration is a random value between 0 and 2 n * interval. The backoff is configured with a maximum duration that will not be exceeded; e.g., by default, the longest duration returned is backoff.DefaultMaxDuration.

Usage

A Backoff is initialised with a call to New. Using zero values causes it to use DefaultMaxDuration and DefaultInterval as the maximum duration and interval.

package something

import "github.com/cloudflare/backoff"

func retryable() {
        b := backoff.New(0, 0)
        for {
                err := someOperation()
                if err == nil {
                    break
                }

                log.Printf("error in someOperation: %v", err)
                <-time.After(b.Duration())
        }

        log.Printf("succeeded after %d tries", b.Tries()+1)
        b.Reset()
}

It can also be used to rate limit code that should retry infinitely, but which does not use Backoff itself.

package something

import (
    "time"

    "github.com/cloudflare/backoff"
)

func retryable() {
        b := backoff.New(0, 0)
        b.SetDecay(30 * time.Second)

        for {
                // b will reset if someOperation returns later than
                // the last call to b.Duration() + 30s.
                err := someOperation()
                if err == nil {
                    break
                }

                log.Printf("error in someOperation: %v", err)
                <-time.After(b.Duration())
        }
}

Tunables

  • NewWithoutJitter creates a Backoff that doesn't use jitter.

The default behaviour is controlled by two variables:

  • DefaultInterval sets the base interval for backoffs created with the zero time.Duration value in the Interval field.
  • DefaultMaxDuration sets the maximum duration for backoffs created with the zero time.Duration value in the MaxDuration field.

Documentation

Overview

Package backoff contains an implementation of an intelligent backoff strategy. It is based on the approach in the AWS architecture blog article titled "Exponential Backoff And Jitter", which is found at http://www.awsarchitectureblog.com/2015/03/backoff.html.

Essentially, the backoff has an interval `time.Duration`; the nth call to backoff will return a `time.Duration` that is 2^n * interval. If jitter is enabled (which is the default behaviour), the duration is a random value between 0 and 2^n * interval. The backoff is configured with a maximum duration that will not be exceeded.

The `New` function will attempt to use the system's cryptographic random number generator to seed a Go math/rand random number source. If this fails, the package will panic on startup.

Index

Examples

Constants

This section is empty.

Variables

View Source
var DefaultInterval = 5 * time.Minute

DefaultInterval is used when a Backoff is initialised with a zero-value Interval.

View Source
var DefaultMaxDuration = 6 * time.Hour

DefaultMaxDuration is maximum amount of time that the backoff will delay for.

Functions

This section is empty.

Types

type Backoff

type Backoff struct {
	// contains filtered or unexported fields
}

A Backoff contains the information needed to intelligently backoff and retry operations using an exponential backoff algorithm. It should be initialised with a call to `New`.

Only use a Backoff from a single goroutine, it is not safe for concurrent access.

func New

func New(max time.Duration, interval time.Duration) *Backoff

New creates a new backoff with the specified max duration and interval. Zero values may be used to use the default values.

Panics if either max or interval is negative.

func NewWithoutJitter

func NewWithoutJitter(max time.Duration, interval time.Duration) *Backoff

NewWithoutJitter works similarly to New, except that the created Backoff will not use jitter.

func (*Backoff) Duration

func (b *Backoff) Duration() time.Duration

Duration returns a time.Duration appropriate for the backoff, incrementing the attempt counter.

func (*Backoff) Reset

func (b *Backoff) Reset()

Reset resets the attempt counter of a backoff.

It should be called when the rate-limited action succeeds.

func (*Backoff) SetDecay

func (b *Backoff) SetDecay(decay time.Duration)

SetDecay sets the duration after which the try counter will be reset. Panics if decay is smaller than 0.

The decay only kicks in if at least the last backoff + decay has elapsed since the last try.

Example
b := NewWithoutJitter(max, interval)
b.SetDecay(decay)

// try 0
fmt.Println(b.Duration())

// try 1
fmt.Println(b.Duration())

// try 2
duration := b.Duration()
fmt.Println(duration)

// try 3, below decay
time.Sleep(duration)
duration = b.Duration()
fmt.Println(duration)

// try 4, resets
time.Sleep(duration + decay)
fmt.Println(b.Duration())
Output:

1ms
2ms
4ms
8ms
1ms

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL