README.md
1backoff
2=======
3
4[![Build Status](https://travis-ci.org/jeffchao/backoff.svg?branch=master)](https://travis-ci.org/jeffchao/backoff)
5[![GoDoc](https://godoc.org/github.com/jeffchao/backoff?status.png)](https://godoc.org/github.com/jeffchao/backoff)
6
7Backoff algorithms are used to space out repeated retries of the same block of code. By gradually decreasing the retry rate, backoff algorithms aim to avoid congestion. This Go backoff library provides a set of backoff algorithms well-known in the computer networks research community. These algorithms are acceptable for use in generalized computation. All algorithms use a uniform distribution of backoff times.
8
9This library provides the following backoff algorithms:
10
111. `Exponential`
122. `Fibonacci`
133. `MILD`
144. `PLEB`
155. `PFB`
16
17each with properties:
18
19```go
20type <all backoff algorithms> struct {
21 Retries int
22 MaxRetries int
23 Delay time.Duration
24 Interval time.Duration // time.Second, time.Millisecond, etc.
25 Slots []time.Duration
26}
27```
28
29
30
31all of which are based off a `Backoff` interface defined as:
32
33```go
34type Backoff interface {
35 Next() bool
36 Retry(func() error) error // Surface the resulting error to the user.
37 Reset()
38}
39```
40
41so you may define additional backoff algorithms of your choice.
42
43### Exponential Backoff
44
45Gradually decrease the retry rate in an exponential manner with base 2. The algorithm is defined as `n = 2^c - 1` where `n` is the backoff delay and `c` is the number of retries.
46
47Example usage:
48
49```go
50e := backoff.Exponential()
51e.Interval = 1 * time.Millisecond
52e.MaxRetries = 5
53
54fooFunc := func() error {
55 // Do some work here
56}
57
58err := e.Retry(fooFunc)
59e.Reset()
60```
61
62### Fibonacci Backoff
63
64Gradually decrease the retry rate using a fibonacci sequence. The algorithm is defined as `n = fib(c - 1) + fib(c - 2); f(0) = 0, f(1) = 1; n >= 0` where `n` is the backoff delay and `c` is the retry slot.
65
66```go
67f := backoff.Fibonacci()
68f.Interval = 1 * time.Millisecond
69f.MaxRetries = 5
70
71fooFunc := func() error {
72 // Do some work here
73}
74
75err := f.Retry(fooFunc)
76f.Reset()
77```
78
79Additionally, the `FibonacciBackoff` struct exposes its delay slots in the form of a slice of `time.Duration`.
80
81```go
82log.Printf("%+v", f.Slots)
83```
84
85### MILD - Multiplicative Increase and Linear Decrease
86
87Gradually increase the retry delay by a factor of 1.5. However, upon successful transmission, decrement the index of the delay slots so that the current delay is the previous value. The retry mechanism thus will not result in a success until the slot index has been decremented to 0. Conversely, the retry mechanism will fail as usual, upon reaching the failed maximum number of retries. The algorithm is defined as follows: `n = min(1.5, n, len(slots)) upon failure; n = max(slots(c) - 1, 0) upon success; n(0) = 0, n(1) = 1` where `n` is the backoff delay, `c` is the retry slot, and `slots` is an array of retry delays.
88
89
90```go
91f := backoff.MILD()
92f.Interval = 1 * time.Millisecond
93f.MaxRetries = 5
94
95fooFunc := func() error {
96 // Do some work here
97}
98
99err := f.Retry(fooFunc)
100f.Reset()
101```
102
103## Author
104
105Jeff Chao, @thejeffchao, http://thejeffchao.com
106