123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051 |
- package frankenphp
- import (
- "sync"
- "time"
- )
- type exponentialBackoff struct {
- backoff time.Duration
- failureCount int
- mu sync.RWMutex
- maxBackoff time.Duration
- minBackoff time.Duration
- maxConsecutiveFailures int
- }
- // recordSuccess resets the backoff and failureCount
- func (e *exponentialBackoff) recordSuccess() {
- e.mu.Lock()
- e.failureCount = 0
- e.backoff = e.minBackoff
- e.mu.Unlock()
- }
- // recordFailure increments the failure count and increases the backoff, it returns true if maxConsecutiveFailures has been reached
- func (e *exponentialBackoff) recordFailure() bool {
- e.mu.Lock()
- e.failureCount += 1
- if e.backoff < e.minBackoff {
- e.backoff = e.minBackoff
- }
- e.backoff = min(e.backoff*2, e.maxBackoff)
- e.mu.Unlock()
- return e.failureCount >= e.maxConsecutiveFailures
- }
- // wait sleeps for the backoff duration if failureCount is non-zero.
- // NOTE: this is not tested and should be kept 'obviously correct' (i.e., simple)
- func (e *exponentialBackoff) wait() {
- e.mu.RLock()
- if e.failureCount == 0 {
- e.mu.RUnlock()
- return
- }
- e.mu.RUnlock()
- time.Sleep(e.backoff)
- }
|