Various performance and correctness improvements.

This commit is contained in:
Jay
2026-04-20 22:41:37 -04:00
parent 72b1ca7ad1
commit daf9f7534e
25 changed files with 577 additions and 297 deletions
+23 -1
View File
@@ -9,12 +9,24 @@ import (
type RetryManager struct {
config *RetryConfig
retryCount int
saturation int
}
func NewRetryManager(config *RetryConfig) *RetryManager {
// saturationCount: retry count at which base delay meets or exceeds MaxDelay.
// Conservative by one to preserve jitter variance near the boundary.
saturation := 0
if config != nil &&
config.InitialDelay > 0 &&
config.InitialDelay <= config.MaxDelay {
ratio := float64(config.MaxDelay) / float64(config.InitialDelay)
saturation = int(math.Ceil(math.Log2(ratio))) + 2
}
return &RetryManager{
config: config,
retryCount: 0,
saturation: saturation,
}
}
@@ -40,8 +52,18 @@ func (r *RetryManager) CalculateDelay() time.Duration {
return 0
}
// if saturation is reached, calculated backoff will always be higher than
// the maximum delay
if r.config != nil && r.retryCount >= r.saturation {
return r.config.MaxDelay
}
// Exponential backoff: InitialDelay * 2^(attempts-1)
backoffMultiplier := math.Pow(2, float64(r.retryCount-1))
shift := r.retryCount - 1
if shift > 62 {
shift = 62
} // prevent overflow
backoffMultiplier := float64(int64(1) << shift)
baseDelay := float64(r.config.InitialDelay) * backoffMultiplier
// Apply jitter: delay * (1 + jitterFactor * (random - 0.5))