60 lines
1.4 KiB
Go
60 lines
1.4 KiB
Go
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
// Copyright © 2023 Thorsten Schubert <tschubert@bafh.org>
|
|
|
|
package retry
|
|
|
|
import "time"
|
|
|
|
type ExponentialBackoff struct {
|
|
initialDelay time.Duration
|
|
currentDelay time.Duration
|
|
maxDelay time.Duration
|
|
maxRetries uint
|
|
currentRetries uint
|
|
}
|
|
|
|
func NewExponentialBackoff(initialDelay time.Duration, maxRetries uint) *ExponentialBackoff {
|
|
return NewExponentialBackoffWithCap(initialDelay, 0, maxRetries)
|
|
}
|
|
|
|
func NewExponentialBackoffWithCap(initialDelay, maxDelay time.Duration, maxRetries uint) *ExponentialBackoff {
|
|
return &ExponentialBackoff{
|
|
initialDelay: initialDelay,
|
|
currentDelay: initialDelay,
|
|
maxDelay: maxDelay,
|
|
maxRetries: maxRetries,
|
|
}
|
|
}
|
|
|
|
func (s *ExponentialBackoff) NextDelay() time.Duration {
|
|
current := s.currentDelay
|
|
if s.maxDelay == 0 || s.currentDelay < s.maxDelay/2 {
|
|
s.currentDelay *= 2
|
|
} else {
|
|
s.currentDelay = s.maxDelay
|
|
}
|
|
return current
|
|
}
|
|
|
|
func (s *ExponentialBackoff) Next() bool {
|
|
if s.currentRetries >= s.maxRetries {
|
|
return false
|
|
}
|
|
s.currentRetries++
|
|
return true
|
|
}
|
|
|
|
func (s *ExponentialBackoff) Retries() (uint, uint) {
|
|
return s.currentRetries, s.maxRetries
|
|
}
|
|
|
|
func (s *ExponentialBackoff) Name() string {
|
|
if s.maxDelay > 0 {
|
|
return "exponential capped"
|
|
}
|
|
return "exponential"
|
|
}
|
|
|
|
func (s *ExponentialBackoff) Reset() {
|
|
s.currentDelay, s.currentRetries = s.initialDelay, 0
|
|
}
|