57 lines
1.0 KiB
Go
57 lines
1.0 KiB
Go
package timer
|
|
|
|
import (
|
|
"time"
|
|
)
|
|
|
|
// RetryOptions 重试配置
|
|
type RetryOptions struct {
|
|
MaxRetries int
|
|
Backoff time.Duration
|
|
Factor float64
|
|
}
|
|
|
|
// RetryOption 重试选项函数
|
|
type RetryOption func(*RetryOptions)
|
|
|
|
// WithMaxRetries 设置最大重试次数
|
|
func WithMaxRetries(n int) RetryOption {
|
|
return func(o *RetryOptions) {
|
|
o.MaxRetries = n
|
|
}
|
|
}
|
|
|
|
// WithBackoff 设置初始等待时间和增长因子
|
|
func WithBackoff(d time.Duration, factor float64) RetryOption {
|
|
return func(o *RetryOptions) {
|
|
o.Backoff = d
|
|
o.Factor = factor
|
|
}
|
|
}
|
|
|
|
// Retry 执行带退避机制的重试
|
|
func Retry(fn func() error, opts ...RetryOption) error {
|
|
o := &RetryOptions{
|
|
MaxRetries: 3,
|
|
Backoff: 100 * time.Millisecond,
|
|
Factor: 2.0,
|
|
}
|
|
for _, opt := range opts {
|
|
opt(o)
|
|
}
|
|
|
|
var err error
|
|
backoff := o.Backoff
|
|
for i := 0; i <= o.MaxRetries; i++ {
|
|
err = fn()
|
|
if err == nil {
|
|
return nil
|
|
}
|
|
if i < o.MaxRetries {
|
|
time.Sleep(backoff)
|
|
backoff = time.Duration(float64(backoff) * o.Factor)
|
|
}
|
|
}
|
|
return err
|
|
}
|