Preface
When writing applications, you sometimes encounter some short-term errors, such as network requests, service link terminal failures, etc. These errors may cause function execution to fail.
However, if the execution may be successful later, then you need to try again in some business scenarios. The concept of retry is very simple, so I won't explain it too much here
Recently, I'm also switching to the golang language. The retry mechanism can be used to practice. The retry function generally needs to support the following parameters.
- execFunc: a retry function that needs to be executed
- interval: the interval for retry
- attempts: the number of attempts
- conditionMode: retry condition mode, error and bool mode (this parameter is used to control the passed execution function return value type detection
Code
package retryimpl import ( "fmt" "time" ) // RetryOptionV2 configuration option functiontype RetryOptionV2 func(retry *RetryV2) // RetryFunc Retry function without return valuetype RetryFunc func() error // RetryFuncWithData Retry function with return valuetype RetryFuncWithData func() (any, error) // RetryV2 retry classtype RetryV2 struct { interval // The interval between retry attempts int // Number of retry} // NewRetryV2 constructorfunc NewRetryV2(opts ...RetryOptionV2) *RetryV2 { retry := RetryV2{ interval: DefaultInterval, attempts: DefaultAttempts, } for _, opt := range opts { opt(&retry) } return &retry } // WithIntervalV2 retry interval configurationfunc WithIntervalV2(interval ) RetryOptionV2 { return func(retry *RetryV2) { = interval } } // WithAttemptsV2 Retry timesfunc WithAttemptsV2(attempts int) RetryOptionV2 { return func(retry *RetryV2) { = attempts } } // DoV2 exposes the execution functionfunc (r *RetryV2) DoV2(executeFunc RetryFunc) error { ("[Retry.DoV2] begin execute func...") retryFuncWithData := func() (any, error) { return nil, executeFunc() } _, err := r.DoV2WithData(retryFuncWithData) return err } // DoV2WithData Exposed to the outside can return datafunc (r *RetryV2) DoV2WithData(execWithDataFunc RetryFuncWithData) (any, error) { ("[Retry.DoV2WithData] begin execute func...") n := 0 for n < { res, err := execWithDataFunc() if err == nil { return res, nil } n++ () } return nil, nil }
Test verification
package retryimpl import ( "errors" "fmt" "testing" "time" ) // TestRetryV2_DoFunc func TestRetryV2_DoFunc(t *) { testSuites := []struct { exceptExecCount int actualExecCount int }{ {exceptExecCount: 3, actualExecCount: 0}, {exceptExecCount: 1, actualExecCount: 1}, } for _, testSuite := range testSuites { retry := NewRetryV2( WithAttemptsV2(), WithIntervalV2(1*), ) err := retry.DoV2(func() error { ("[TestRetry_DoFuncBoolMode] was called ...") if == 1 { return nil } ++ return ("raise error") }) if err != nil { ("[TestRetryV2_DoFunc] retyr.DoV2 execute failed and err:%+v", err) continue } if != { ("[TestRetryV2_DoFunc] got actualExecCount:%v != exceptExecCount:%v", , ) } } } // TestRetryV2_DoFuncWithData func TestRetryV2_DoFuncWithData(t *) { testSuites := []struct { exceptExecCount int resMessage string }{ {exceptExecCount: 3, resMessage: "fail"}, {exceptExecCount: 1, resMessage: "ok"}, } for _, testSuite := range testSuites { retry := NewRetryV2( WithAttemptsV2(), WithIntervalV2(1*), ) res, err := retry.DoV2WithData(func() (any, error) { ("[TestRetryV2_DoFuncWithData] DoV2WithData was called ...") if == 1 { return , nil } return , ("raise error") }) if err != nil { ("[TestRetryV2_DoFuncWithData] retyr.DoV2 execute failed and err:%+v", err) continue } if val, ok := res.(string); ok && val != { ("[TestRetryV2_DoFuncWithData] got unexcept result:%+v", val) continue } ("[TestRetryV2_DoFuncWithData] got result:%+v", ) } }
refer to:GitCode - Developer's code home
This is the end of this article about the implementation of the Golang function retry mechanism. For more related content of the Golang retry mechanism, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!