126 lines
2.8 KiB
Go
126 lines
2.8 KiB
Go
package reconnect
|
||
|
||
import "time"
|
||
|
||
// Strategy 重连策略接口
|
||
type Strategy interface {
|
||
// NextDelay 返回下一次重试的延迟时间
|
||
// attempt 是当前重试次数(从1开始)
|
||
NextDelay(attempt int) time.Duration
|
||
|
||
// Reset 重置策略状态
|
||
Reset()
|
||
}
|
||
|
||
// ExponentialBackoff 指数退避策略
|
||
type ExponentialBackoff struct {
|
||
initialDelay time.Duration
|
||
maxDelay time.Duration
|
||
multiplier float64
|
||
}
|
||
|
||
// NewExponentialBackoff 创建指数退避策略
|
||
func NewExponentialBackoff(initialDelay, maxDelay time.Duration, multiplier float64) *ExponentialBackoff {
|
||
if multiplier <= 0 {
|
||
multiplier = 2.0
|
||
}
|
||
return &ExponentialBackoff{
|
||
initialDelay: initialDelay,
|
||
maxDelay: maxDelay,
|
||
multiplier: multiplier,
|
||
}
|
||
}
|
||
|
||
// NextDelay 计算下一次延迟时间
|
||
func (e *ExponentialBackoff) NextDelay(attempt int) time.Duration {
|
||
if attempt <= 0 {
|
||
attempt = 1
|
||
}
|
||
delay := float64(e.initialDelay)
|
||
for i := 1; i < attempt; i++ {
|
||
delay *= e.multiplier
|
||
if time.Duration(delay) >= e.maxDelay {
|
||
return e.maxDelay
|
||
}
|
||
}
|
||
if time.Duration(delay) > e.maxDelay {
|
||
return e.maxDelay
|
||
}
|
||
return time.Duration(delay)
|
||
}
|
||
|
||
// Reset 重置策略
|
||
func (e *ExponentialBackoff) Reset() {
|
||
// 无状态,无需重置
|
||
}
|
||
|
||
// FixedInterval 固定间隔策略
|
||
type FixedInterval struct {
|
||
interval time.Duration
|
||
}
|
||
|
||
// NewFixedInterval 创建固定间隔策略
|
||
func NewFixedInterval(interval time.Duration) *FixedInterval {
|
||
return &FixedInterval{
|
||
interval: interval,
|
||
}
|
||
}
|
||
|
||
// NextDelay 返回固定延迟时间
|
||
func (f *FixedInterval) NextDelay(attempt int) time.Duration {
|
||
return f.interval
|
||
}
|
||
|
||
// Reset 重置策略
|
||
func (f *FixedInterval) Reset() {
|
||
// 无状态,无需重置
|
||
}
|
||
|
||
// LinearBackoff 线性退避策略
|
||
type LinearBackoff struct {
|
||
initialDelay time.Duration
|
||
maxDelay time.Duration
|
||
increment time.Duration
|
||
}
|
||
|
||
// NewLinearBackoff 创建线性退避策略
|
||
func NewLinearBackoff(initialDelay, maxDelay, increment time.Duration) *LinearBackoff {
|
||
return &LinearBackoff{
|
||
initialDelay: initialDelay,
|
||
maxDelay: maxDelay,
|
||
increment: increment,
|
||
}
|
||
}
|
||
|
||
// NextDelay 计算下一次延迟时间
|
||
func (l *LinearBackoff) NextDelay(attempt int) time.Duration {
|
||
if attempt <= 0 {
|
||
attempt = 1
|
||
}
|
||
delay := l.initialDelay + time.Duration(attempt-1)*l.increment
|
||
if delay > l.maxDelay {
|
||
return l.maxDelay
|
||
}
|
||
return delay
|
||
}
|
||
|
||
// Reset 重置策略
|
||
func (l *LinearBackoff) Reset() {
|
||
// 无状态,无需重置
|
||
}
|
||
|
||
// NewStrategy 根据配置创建策略
|
||
func NewStrategy(cfg Config) Strategy {
|
||
switch cfg.Strategy {
|
||
case StrategyFixedInterval:
|
||
return NewFixedInterval(cfg.InitialDelay)
|
||
case StrategyLinearBackoff:
|
||
return NewLinearBackoff(cfg.InitialDelay, cfg.MaxDelay, cfg.LinearIncrement)
|
||
case StrategyExponentialBackoff:
|
||
fallthrough
|
||
default:
|
||
return NewExponentialBackoff(cfg.InitialDelay, cfg.MaxDelay, cfg.Multiplier)
|
||
}
|
||
}
|
||
|