Files
exchange_go/pkg/retryhelper/retryhelper.go
2025-07-26 09:09:09 +08:00

55 lines
1.6 KiB
Go

package retryhelper
import (
"fmt"
"math"
"time"
)
// RetryOptions 定义重试的配置项
type RetryOptions struct {
MaxRetries int // 最大重试次数
InitialInterval time.Duration // 初始重试间隔
MaxInterval time.Duration // 最大重试间隔
BackoffFactor float64 // 指数退避的增长因子
RetryableErrFn func(error) bool // 用于判断是否为可重试错误的函数(可选)
}
func DefaultRetryOptions() RetryOptions {
return RetryOptions{
MaxRetries: 3,
InitialInterval: 150 * time.Millisecond,
MaxInterval: 3 * time.Second,
BackoffFactor: 2.0,
}
}
// Retry 重试通用函数(用于没有返回值的函数)
func Retry(op func() error, opts RetryOptions) error {
_, err := RetryWithResult(func() (struct{}, error) {
return struct{}{}, op()
}, opts)
return err
}
// RetryWithResult 重试通用函数(用于带返回值的函数)
func RetryWithResult[T any](op func() (T, error), opts RetryOptions) (result T, err error) {
interval := opts.InitialInterval
for attempt := 0; attempt <= opts.MaxRetries; attempt++ {
result, err = op()
if err == nil {
return result, nil
}
if opts.RetryableErrFn != nil && !opts.RetryableErrFn(err) {
return result, err
}
if attempt < opts.MaxRetries {
time.Sleep(interval)
interval = time.Duration(math.Min(float64(opts.MaxInterval), float64(interval)*opts.BackoffFactor))
}
}
return result, fmt.Errorf("retry failed after %d attempts, last error: %w", opts.MaxRetries+1, err)
}