mirror of
https://github.com/dunglas/frankenphp.git
synced 2025-09-26 19:41:13 +08:00
52 lines
1.1 KiB
Go
52 lines
1.1 KiB
Go
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)
|
|
}
|