当前位置: 代码网 > it编程>前端脚本>Golang > Golang函数重试机制实现代码

Golang函数重试机制实现代码

2024年05月26日 Golang 我要评论
前言在编写应用程序时,有时候会遇到一些短暂的错误,例如网络请求、服务链接终端失败等,这些错误可能导致函数执行失败。但是如果稍后执行可能会成功,那么在一些业务场景下就需要重试了,重试的概念很简单,这里就

前言

在编写应用程序时,有时候会遇到一些短暂的错误,例如网络请求、服务链接终端失败等,这些错误可能导致函数执行失败。
但是如果稍后执行可能会成功,那么在一些业务场景下就需要重试了,重试的概念很简单,这里就不做过多阐述了

最近也正好在转golang语言,重试机制正好可以拿来练手,重试功能一般需要支持以下参数

  • execfunc:需要被执行的重试的函数
  • interval:重试的间隔时长
  • attempts:尝试次数
  • conditionmode:重试的条件模式,error和bool模式(这个参数用于控制传递的执行函数返回值类型检测

代码

package retryimpl
import (
	"fmt"
	"time"
)
// 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 := 0
	for n < r.attempts {
		res, err := execwithdatafunc()
		if err == nil {
			return res, nil
		}
		n++
		time.sleep(r.interval)
	}
	return nil, nil
}

测试验证

package retryimpl
import (
	"errors"
	"fmt"
	"testing"
	"time"
)
// testretryv2_dofunc
func testretryv2_dofunc(t *testing.t) {
	testsuites := []struct {
		exceptexeccount int
		actualexeccount 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.actualexeccount++
			return 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 int
		resmessage      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 - 开发者的代码家园

到此这篇关于golang函数重试机制实现的文章就介绍到这了,更多相关golang重试机制内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com