Golang之sync.waitGroup、sync.ErrGroup.Wait和RetryOnErr

本文介绍了Go语言包`proj_test/errlib`中的`RetryOnErr`函数,它结合了同步机制和错误处理,展示了如何在遇到错误时进行重试并捕获最终结果。通过`sync.WaitGroup`和自定义回退策略,作者详细剖析了这一实用工具在实际项目中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package main

import (
	"fmt"
	"github.com/sirupsen/logrus"
	"proj_test/errlib"
)

func main() {
	times := 0
	retryErr := errlib.RetryOnErr(errlib.NewDefaultRetryConf(), func() error {
		times++
		return apply()
	})
	if retryErr != nil {
		logrus.Errorf("catch error")
	}
}

func apply() error {
	logrus.Infof("apply")
	// 编写业务逻辑
	return fmt.Errorf("error")
}
package errlib

import (
	"k8s.io/apimachinery/pkg/util/wait"
	"time"
)

func NewDefaultRetryConf() wait.Backoff {
	return wait.Backoff{
		Steps:    5,
		Duration: time.Duration(2) * time.Second,
		Factor:   1.0,
		Jitter:   0.1,
	}
}
func RetryOnErr(bacoff wait.Backoff, fn func() error) error {
	return OnErr(bacoff, IsError, fn)
}

func IsError(err error) bool {
	return err != nil
}

func OnErr(backoff wait.Backoff, retriable func(error) bool, fn func() error) error {
	var lastConflictErr error
	err := wait.ExponentialBackoff(backoff, func() (bool, error) {
		err := fn()
		switch {
		case err == nil:
			return true, nil
		case retriable(err):
			lastConflictErr = err
			return false, nil
		default:
			return false, err
		}
	})
	if err == wait.ErrWaitTimeout {
		err = lastConflictErr
	}
	return err
}

sync.WaitGroup实现一个goroutine等待一组goroutine任务结束,更好的实现了任务同步,但是waitGroup却无法返回错误。并且waitgroup会允许go先到GMP的g,g在p的队列进行等待而不分配m,从而实现waitgroup的等待,则不是直接不允许进入g


sync.ErrGroup在sync.WaitGroup功能的基础上,增加了错误传递,以及在发生不可恢复的错误时取消整个goroutine集合,或者等待超时。

RetryOnErr在sync.ErrGroup的基础上增加了出错重试功能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值