Skip to content
Simple backoff algorithm in Go (golang)
Go
Branch: master
Clone or download
jpillora Merge pull request #15 from josedh/master
Clone method and splitting if-else statement
Latest commit 3050d21 Sep 9, 2018
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
LICENSE move license from README into LICENSE (closes #10) Feb 22, 2017
README.md docs Sep 18, 2017
backoff.go adding copy feature and removing nested if/else Sep 3, 2018
backoff_test.go adding copy feature and removing nested if/else Sep 3, 2018

README.md

Backoff

A simple exponential backoff counter in Go (Golang)

GoDoc Circle CI

Install

$ go get -v github.com/jpillora/backoff

Usage

Backoff is a time.Duration counter. It starts at Min. After every call to Duration() it is multiplied by Factor. It is capped at Max. It returns to Min on every call to Reset(). Jitter adds randomness (see below). Used in conjunction with the time package.


Simple example

b := &backoff.Backoff{
	//These are the defaults
	Min:    100 * time.Millisecond,
	Max:    10 * time.Second,
	Factor: 2,
	Jitter: false,
}

fmt.Printf("%s\n", b.Duration())
fmt.Printf("%s\n", b.Duration())
fmt.Printf("%s\n", b.Duration())

fmt.Printf("Reset!\n")
b.Reset()

fmt.Printf("%s\n", b.Duration())
100ms
200ms
400ms
Reset!
100ms

Example using net package

b := &backoff.Backoff{
    Max:    5 * time.Minute,
}

for {
	conn, err := net.Dial("tcp", "example.com:5309")
	if err != nil {
		d := b.Duration()
		fmt.Printf("%s, reconnecting in %s", err, d)
		time.Sleep(d)
		continue
	}
	//connected
	b.Reset()
	conn.Write([]byte("hello world!"))
	// ... Read ... Write ... etc
	conn.Close()
	//disconnected
}

Example using Jitter

Enabling Jitter adds some randomization to the backoff durations. See Amazon's writeup of performance gains using jitter. Seeding is not necessary but doing so gives repeatable results.

import "math/rand"

b := &backoff.Backoff{
	Jitter: true,
}

rand.Seed(42)

fmt.Printf("%s\n", b.Duration())
fmt.Printf("%s\n", b.Duration())
fmt.Printf("%s\n", b.Duration())

fmt.Printf("Reset!\n")
b.Reset()

fmt.Printf("%s\n", b.Duration())
fmt.Printf("%s\n", b.Duration())
fmt.Printf("%s\n", b.Duration())
100ms
106.600049ms
281.228155ms
Reset!
100ms
104.381845ms
214.957989ms

Documentation

https://godoc.org/github.com/jpillora/backoff

Credits

Forked from some JavaScript written by @tj

You can’t perform that action at this time.