forked from OneOfOne/otk
-
Notifications
You must be signed in to change notification settings - Fork 0
/
retry.go
47 lines (39 loc) · 983 Bytes
/
retry.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
41
42
43
44
45
46
47
package otk
import (
"context"
"time"
)
// Retry is an alias for RetryCtx(context.Background(), fn, attempts, delay, backoffMod)
func Retry(fn func() error, attempts uint, delay time.Duration, backoffMod float64) error {
return RetryCtx(context.Background(), fn, attempts, delay, backoffMod)
}
// RetryCtx calls fn every (delay * backoffMod) until it returns nil, the passed ctx is done or attempts are reached.
func RetryCtx(ctx context.Context, fn func() error, attempts uint, delay time.Duration, backoffMod float64) error {
if delay == 0 {
delay = time.Second
}
if attempts == 0 {
attempts = 1
}
if backoffMod == 0 {
backoffMod = 1
}
ret := make(chan error, 1)
go func() {
var err error
for ; attempts > 0; attempts-- {
if err = fn(); err == nil {
break
}
time.Sleep(delay)
delay = time.Duration(float64(delay) * backoffMod)
}
ret <- err
}()
select {
case err := <-ret:
return err
case <-ctx.Done():
return ctx.Err()
}
}