2015-02-28 09:21:18 +03:00
# Backoff
2016-08-03 05:50:56 +03:00
A simple exponential backoff counter in Go (Golang)
2015-02-28 09:21:18 +03:00
2016-03-02 02:05:12 +03:00
[![GoDoc ](https://godoc.org/github.com/jpillora/backoff?status.svg )](https://godoc.org/github.com/jpillora/backoff) [![Circle CI ](https://circleci.com/gh/jpillora/backoff.svg?style=shield )](https://circleci.com/gh/jpillora/backoff)
2015-03-03 01:01:21 +03:00
2015-03-04 07:21:35 +03:00
### Install
```
$ go get -v github.com/jpillora/backoff
```
2015-03-05 14:06:27 +03:00
### Usage
2015-02-28 09:21:18 +03:00
2015-03-07 05:35:25 +03:00
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](#example-using-jitter)). Used in conjunction with the `time` package.
2015-02-28 09:21:18 +03:00
2015-03-05 14:06:27 +03:00
---
2015-03-07 05:34:50 +03:00
#### Simple example
2015-03-05 14:06:27 +03:00
2015-02-28 09:21:18 +03:00
``` go
b := & backoff.Backoff{
//These are the defaults
Min: 100 * time.Millisecond,
Max: 10 * time.Second,
Factor: 2,
2015-03-06 17:42:27 +03:00
Jitter: false,
2015-02-28 09:21:18 +03:00
}
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
```
2015-03-05 14:06:27 +03:00
---
2015-03-07 05:34:50 +03:00
#### Example using `net` package
2015-03-05 14:06:27 +03:00
``` go
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
}
```
2015-03-07 05:34:50 +03:00
---
#### Example using `Jitter`
2015-03-06 17:42:27 +03:00
2015-03-07 05:34:50 +03:00
Enabling `Jitter` adds some randomization to the backoff durations. [See Amazon's writeup of performance gains using jitter ](http://www.awsarchitectureblog.com/2015/03/backoff.html ). Seeding is not necessary but doing so gives repeatable results.
2015-03-06 17:42:27 +03:00
```go
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
```
2016-08-03 05:50:56 +03:00
#### Documentation
https://godoc.org/github.com/jpillora/backoff
2015-02-28 09:21:18 +03:00
#### Credits
2017-02-22 03:06:34 +03:00
Forked from some JavaScript written by [@tj ](https://github.com/tj )