-
Notifications
You must be signed in to change notification settings - Fork 8
/
retry.go
57 lines (51 loc) · 1.83 KB
/
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
48
49
50
51
52
53
54
55
56
57
package retry
import (
"context"
"fmt"
"time"
"github.com/avast/retry-go"
"github.com/go-logr/logr"
"github.com/ARM-software/golang-utils/utils/commonerrors"
)
// RetryIf will retry fn when the value returned from retryConditionFn is true
func RetryIf(ctx context.Context, logger logr.Logger, retryPolicy *RetryPolicyConfiguration, fn func() error, msgOnRetry string, retryConditionFn func(err error) bool) error {
if retryPolicy == nil {
return fmt.Errorf("%w: missing retry policy configuration", commonerrors.ErrUndefined)
}
if !retryPolicy.Enabled {
return fn()
}
var retryType retry.DelayTypeFunc
switch {
case retryPolicy.LinearBackOffEnabled:
retryType = retry.CombineDelay(retry.FixedDelay, retry.RandomDelay)
case retryPolicy.BackOffEnabled:
retryType = retry.BackOffDelay
default:
retryType = retry.FixedDelay
}
return commonerrors.ConvertContextError(
retry.Do(
fn,
retry.OnRetry(func(n uint, err error) {
logger.Error(err, fmt.Sprintf("%v (attempt #%v)", msgOnRetry, n+1), "attempt", n+1)
}),
retry.Delay(retryPolicy.RetryWaitMin),
retry.MaxDelay(retryPolicy.RetryWaitMax),
retry.MaxJitter(25*time.Millisecond),
retry.DelayType(retryType),
retry.Attempts(uint(retryPolicy.RetryMax)),
retry.RetryIf(retryConditionFn),
retry.LastErrorOnly(true),
retry.Context(ctx),
),
)
}
// RetryOnError allows the caller to retry fn when the error returned by fn is retriable
// as in of the type specified by retriableErr. backoff defines the maximum retries and the wait
// interval between two retries.
func RetryOnError(ctx context.Context, logger logr.Logger, retryPolicy *RetryPolicyConfiguration, fn func() error, msgOnRetry string, retriableErr ...error) error {
return RetryIf(ctx, logger, retryPolicy, fn, msgOnRetry, func(err error) bool {
return commonerrors.Any(err, retriableErr...)
})
}