feat: retry ignore specified errors (#3808)
This commit is contained in:
@@ -2,6 +2,7 @@ package fx
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/errorx"
|
"github.com/zeromicro/go-zero/core/errorx"
|
||||||
@@ -14,9 +15,10 @@ type (
|
|||||||
RetryOption func(*retryOptions)
|
RetryOption func(*retryOptions)
|
||||||
|
|
||||||
retryOptions struct {
|
retryOptions struct {
|
||||||
times int
|
times int
|
||||||
interval time.Duration
|
interval time.Duration
|
||||||
timeout time.Duration
|
timeout time.Duration
|
||||||
|
IgnoreErrors []error
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -62,6 +64,11 @@ func retry(ctx context.Context, fn func(errChan chan error, retryCount int), opt
|
|||||||
select {
|
select {
|
||||||
case err := <-errChan:
|
case err := <-errChan:
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
for _, ignoreErr := range options.IgnoreErrors {
|
||||||
|
if errors.Is(err, ignoreErr) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
berr.Add(err)
|
berr.Add(err)
|
||||||
} else {
|
} else {
|
||||||
return nil
|
return nil
|
||||||
@@ -103,6 +110,13 @@ func WithTimeout(timeout time.Duration) RetryOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithIgnoreErrors Ignore the specified errors
|
||||||
|
func WithIgnoreErrors(IgnoreErrors []error) RetryOption {
|
||||||
|
return func(options *retryOptions) {
|
||||||
|
options.IgnoreErrors = IgnoreErrors
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func newRetryOptions() *retryOptions {
|
func newRetryOptions() *retryOptions {
|
||||||
return &retryOptions{
|
return &retryOptions{
|
||||||
times: defaultRetryTimes,
|
times: defaultRetryTimes,
|
||||||
|
|||||||
@@ -97,6 +97,24 @@ func TestRetryWithInterval(t *testing.T) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRetryWithWithIgnoreErrors(t *testing.T) {
|
||||||
|
ignoreErr1 := errors.New("ignore error1")
|
||||||
|
ignoreErr2 := errors.New("ignore error2")
|
||||||
|
ignoreErrs := []error{ignoreErr1, ignoreErr2}
|
||||||
|
|
||||||
|
assert.Nil(t, DoWithRetry(func() error {
|
||||||
|
return ignoreErr1
|
||||||
|
}, WithIgnoreErrors(ignoreErrs)))
|
||||||
|
|
||||||
|
assert.Nil(t, DoWithRetry(func() error {
|
||||||
|
return ignoreErr2
|
||||||
|
}, WithIgnoreErrors(ignoreErrs)))
|
||||||
|
|
||||||
|
assert.NotNil(t, DoWithRetry(func() error {
|
||||||
|
return errors.New("any")
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
func TestRetryCtx(t *testing.T) {
|
func TestRetryCtx(t *testing.T) {
|
||||||
t.Run("with timeout", func(t *testing.T) {
|
t.Run("with timeout", func(t *testing.T) {
|
||||||
assert.NotNil(t, DoWithRetryCtx(context.Background(), func(ctx context.Context, retryCount int) error {
|
assert.NotNil(t, DoWithRetryCtx(context.Background(), func(ctx context.Context, retryCount int) error {
|
||||||
|
|||||||
Reference in New Issue
Block a user