1package slack
2
3import (
4	"math/rand"
5	"time"
6)
7
8// This one was ripped from https://github.com/jpillora/backoff/blob/master/backoff.go
9
10// Backoff is a time.Duration counter. It starts at Min.  After every
11// call to Duration() it is multiplied by Factor.  It is capped at
12// Max. It returns to Min on every call to Reset().  Used in
13// conjunction with the time package.
14type backoff struct {
15	attempts int
16	// Initial value to scale out
17	Initial time.Duration
18	// Jitter value randomizes an additional delay between 0 and Jitter
19	Jitter time.Duration
20	// Max maximum values of the backoff
21	Max time.Duration
22}
23
24// Returns the current value of the counter and then multiplies it
25// Factor
26func (b *backoff) Duration() (dur time.Duration) {
27	// Zero-values are nonsensical, so we use
28	// them to apply defaults
29	if b.Max == 0 {
30		b.Max = 10 * time.Second
31	}
32
33	if b.Initial == 0 {
34		b.Initial = 100 * time.Millisecond
35	}
36
37	// calculate this duration
38	if dur = time.Duration(1 << uint(b.attempts)); dur > 0 {
39		dur = dur * b.Initial
40	} else {
41		dur = b.Max
42	}
43
44	if b.Jitter > 0 {
45		dur = dur + time.Duration(rand.Intn(int(b.Jitter)))
46	}
47
48	// bump attempts count
49	b.attempts++
50
51	return dur
52}
53
54//Resets the current value of the counter back to Min
55func (b *backoff) Reset() {
56	b.attempts = 0
57}
58