-
Notifications
You must be signed in to change notification settings - Fork 88
/
error_backoff.go
40 lines (36 loc) · 1.02 KB
/
error_backoff.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package util
import (
"sync"
"time"
)
// ErrorBackoff keeps track of last time an error was logged to prevent duplicating the OnError
// function. Errors are considered the same if the error text matches exactly. Only last error is
// remembered, so if error changes every time, every OnError function will be executed. The period
// is doubled every time OnError is called until the max period is reached.
type ErrorBackoff struct {
MinPeriod time.Duration
MaxPeriod time.Duration
period time.Duration
lastError error
lastErrorTimeLock sync.Mutex
lastErrorTime time.Time
}
func (r *ErrorBackoff) OnError(err error, fn func()) {
r.lastErrorTimeLock.Lock()
defer r.lastErrorTimeLock.Unlock()
if r.lastError != nil && r.lastError.Error() == err.Error() {
d := time.Since(r.lastErrorTime)
if d < r.period {
return
}
r.period = r.period * 2
if r.period > r.MaxPeriod {
r.period = r.MaxPeriod
}
} else {
r.period = r.MinPeriod
}
r.lastError = err
r.lastErrorTime = time.Now()
fn()
}