石家庄网站建设推广电话,网易暴雪最新消息,西安发布信息的平台,白山住房与城乡建设局网站前言
在编写应用程序时#xff0c;有时候会遇到一些短暂的错误#xff0c;例如网络请求、服务链接终端失败等#xff0c;这些错误可能导致函数执行失败。 但是如果稍后执行可能会成功#xff0c;那么在一些业务场景下就需要重试了#xff0c;重试的概念很简单#xff0c…前言
在编写应用程序时有时候会遇到一些短暂的错误例如网络请求、服务链接终端失败等这些错误可能导致函数执行失败。 但是如果稍后执行可能会成功那么在一些业务场景下就需要重试了重试的概念很简单这里就不做过多阐述了
最近也正好在转golang语言重试机制正好可以拿来练手重试功能一般需要支持以下参数
execFunc需要被执行的重试的函数interval重试的间隔时长attempts尝试次数conditionMode重试的条件模式error和bool模式这个参数用于控制传递的执行函数返回值类型检测 代码
package retryimplimport (fmttime
)// RetryOptionV2 配置选项函数
type RetryOptionV2 func(retry *RetryV2)// RetryFunc 不带返回值的重试函数
type RetryFunc func() error// RetryFuncWithData 带返回值的重试函数
type RetryFuncWithData func() (any, error)// RetryV2 重试类
type RetryV2 struct {interval time.Duration // 重试的间隔时长attempts int // 重试次数
}// NewRetryV2 构造函数
func NewRetryV2(opts ...RetryOptionV2) *RetryV2 {retry : RetryV2{interval: DefaultInterval,attempts: DefaultAttempts,}for _, opt : range opts {opt(retry)}return retry
}// WithIntervalV2 重试的时间间隔配置
func WithIntervalV2(interval time.Duration) RetryOptionV2 {return func(retry *RetryV2) {retry.interval interval}
}// WithAttemptsV2 重试的次数
func WithAttemptsV2(attempts int) RetryOptionV2 {return func(retry *RetryV2) {retry.attempts attempts}
}// DoV2 对外暴露的执行函数
func (r *RetryV2) DoV2(executeFunc RetryFunc) error {fmt.Println([Retry.DoV2] begin execute func...)retryFuncWithData : func() (any, error) {return nil, executeFunc()}_, err : r.DoV2WithData(retryFuncWithData)return err
}// DoV2WithData 对外暴露知的执行函数可以返回数据
func (r *RetryV2) DoV2WithData(execWithDataFunc RetryFuncWithData) (any, error) {fmt.Println([Retry.DoV2WithData] begin execute func...)n : 0for n r.attempts {res, err : execWithDataFunc()if err nil {return res, nil}ntime.Sleep(r.interval)}return nil, nil
}测试验证
package retryimplimport (errorsfmttestingtime
)// TestRetryV2_DoFunc
func TestRetryV2_DoFunc(t *testing.T) {testSuites : []struct {exceptExecCount intactualExecCount int}{{exceptExecCount: 3, actualExecCount: 0},{exceptExecCount: 1, actualExecCount: 1},}for _, testSuite : range testSuites {retry : NewRetryV2(WithAttemptsV2(testSuite.exceptExecCount),WithIntervalV2(1*time.Second),)err : retry.DoV2(func() error {fmt.Println([TestRetry_DoFuncBoolMode] was called ...)if testSuite.exceptExecCount 1 {return nil}testSuite.actualExecCountreturn errors.New(raise error)})if err ! nil {t.Errorf([TestRetryV2_DoFunc] retyr.DoV2 execute failed and err:%v, err)continue}if testSuite.actualExecCount ! testSuite.exceptExecCount {t.Errorf([TestRetryV2_DoFunc] got actualExecCount:%v ! exceptExecCount:%v, testSuite.actualExecCount, testSuite.exceptExecCount)}}}// TestRetryV2_DoFuncWithData
func TestRetryV2_DoFuncWithData(t *testing.T) {testSuites : []struct {exceptExecCount intresMessage string}{{exceptExecCount: 3, resMessage: fail},{exceptExecCount: 1, resMessage: ok},}for _, testSuite : range testSuites {retry : NewRetryV2(WithAttemptsV2(testSuite.exceptExecCount),WithIntervalV2(1*time.Second),)res, err : retry.DoV2WithData(func() (any, error) {fmt.Println([TestRetryV2_DoFuncWithData] DoV2WithData was called ...)if testSuite.exceptExecCount 1 {return testSuite.resMessage, nil}return testSuite.resMessage, errors.New(raise error)})if err ! nil {t.Errorf([TestRetryV2_DoFuncWithData] retyr.DoV2 execute failed and err:%v, err)continue}if val, ok : res.(string); ok val ! testSuite.resMessage {t.Errorf([TestRetryV2_DoFuncWithData] got unexcept result:%v, val)continue}t.Logf([TestRetryV2_DoFuncWithData] got result:%v, testSuite.resMessage)}}参考GitCode - 开发者的代码家园