forked from mirror/backoff
initial, tests passing
This commit is contained in:
commit
34204cc40b
|
@ -0,0 +1,63 @@
|
|||
# Backoff
|
||||
|
||||
A simple backoff algorithm in Go (Golang)
|
||||
|
||||
# Usage
|
||||
|
||||
Starts at `Min`, multiplied by `Factor` every call to
|
||||
`Duration()` where it is capped at `Max`. Commonly used
|
||||
in conjunction with `time.Sleep(duration)`.
|
||||
|
||||
``` go
|
||||
|
||||
b := &backoff.Backoff{
|
||||
//These are the defaults
|
||||
Min: 100 * time.Millisecond,
|
||||
Max: 10 * time.Second,
|
||||
Factor: 2,
|
||||
}
|
||||
|
||||
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
|
||||
```
|
||||
|
||||
#### Credits
|
||||
|
||||
Ported from some JavaScript written by [@tj](https://github.com/tj)
|
||||
|
||||
#### MIT License
|
||||
|
||||
Copyright © 2015 Jaime Pillora <dev@jpillora.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
'Software'), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -0,0 +1,38 @@
|
|||
package backoff
|
||||
|
||||
import (
|
||||
"math"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Backoff struct {
|
||||
attempts, Factor int
|
||||
curr, Min, Max time.Duration
|
||||
}
|
||||
|
||||
func (b *Backoff) Duration() time.Duration {
|
||||
//abit hacky though, if zero-value, apply defaults
|
||||
if b.Min == 0 {
|
||||
b.Min = 100 * time.Millisecond
|
||||
}
|
||||
if b.Max == 0 {
|
||||
b.Max = 10 * time.Second
|
||||
}
|
||||
if b.Factor == 0 {
|
||||
b.Factor = 2
|
||||
}
|
||||
if b.curr == 0 {
|
||||
b.curr = b.Min
|
||||
}
|
||||
|
||||
//calculate next duration in ms
|
||||
ms := float64(b.curr) * math.Pow(float64(b.Factor), float64(b.attempts))
|
||||
//bump attempts count
|
||||
b.attempts++
|
||||
//return as a time.Duration
|
||||
return time.Duration(math.Min(ms, float64(b.Max)))
|
||||
}
|
||||
|
||||
func (b *Backoff) Reset() {
|
||||
b.attempts = 0
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package backoff
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func Test1(t *testing.T) {
|
||||
|
||||
b := &Backoff{
|
||||
Min: 100 * time.Millisecond,
|
||||
Max: 10 * time.Second,
|
||||
Factor: 2,
|
||||
}
|
||||
|
||||
if b.Duration() != 100*time.Millisecond {
|
||||
t.Error("Should be 100ms")
|
||||
}
|
||||
|
||||
if b.Duration() != 200*time.Millisecond {
|
||||
t.Error("Should be 200ms")
|
||||
}
|
||||
|
||||
if b.Duration() != 400*time.Millisecond {
|
||||
t.Error("Should be 400ms")
|
||||
}
|
||||
|
||||
b.Reset()
|
||||
|
||||
if b.Duration() != 100*time.Millisecond {
|
||||
t.Error("Should be 100ms again")
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue