Files
reconnect/strategy.go
2025-12-18 15:11:02 +08:00

126 lines
2.8 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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)
}
}