From 81f0039db2d6eb5e64ab6ed7af9b825492189f4a Mon Sep 17 00:00:00 2001 From: fearlessfei <573088370@qq.com> Date: Fri, 22 Dec 2023 16:52:37 +0800 Subject: [PATCH] feat: retry ignore specified errors --- core/fx/retry.go | 20 +++++++++++++++++--- core/fx/retry_test.go | 18 ++++++++++++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/core/fx/retry.go b/core/fx/retry.go index e79c900224fc..1aa002a25d57 100644 --- a/core/fx/retry.go +++ b/core/fx/retry.go @@ -2,6 +2,7 @@ package fx import ( "context" + "errors" "time" "github.com/zeromicro/go-zero/core/errorx" @@ -14,9 +15,10 @@ type ( RetryOption func(*retryOptions) retryOptions struct { - times int - interval time.Duration - timeout time.Duration + times int + interval 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 { case err := <-errChan: if err != nil { + for _, ignoreErr := range options.IgnoreErrors { + if errors.Is(err, ignoreErr) { + return nil + } + } berr.Add(err) } else { 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 { return &retryOptions{ times: defaultRetryTimes, diff --git a/core/fx/retry_test.go b/core/fx/retry_test.go index 045d782af594..5a8d06b69960 100644 --- a/core/fx/retry_test.go +++ b/core/fx/retry_test.go @@ -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) { t.Run("with timeout", func(t *testing.T) { assert.NotNil(t, DoWithRetryCtx(context.Background(), func(ctx context.Context, retryCount int) error {