52 lines
1.1 KiB
Go
52 lines
1.1 KiB
Go
|
|
package brave
|
||
|
|
|
||
|
|
import (
|
||
|
|
"sync"
|
||
|
|
"time"
|
||
|
|
)
|
||
|
|
|
||
|
|
const (
|
||
|
|
breakerFailureThreshold = 5
|
||
|
|
breakerCooldown = 2 * time.Minute
|
||
|
|
)
|
||
|
|
|
||
|
|
type breakerState struct {
|
||
|
|
mu sync.Mutex
|
||
|
|
failures int
|
||
|
|
openUntil time.Time
|
||
|
|
}
|
||
|
|
|
||
|
|
var globalBreaker breakerState
|
||
|
|
|
||
|
|
// BreakerOpen reports whether Brave calls should be skipped due to recent failures.
|
||
|
|
func BreakerOpen() bool {
|
||
|
|
globalBreaker.mu.Lock()
|
||
|
|
defer globalBreaker.mu.Unlock()
|
||
|
|
return time.Now().Before(globalBreaker.openUntil)
|
||
|
|
}
|
||
|
|
|
||
|
|
func recordBreakerSuccess() {
|
||
|
|
globalBreaker.mu.Lock()
|
||
|
|
defer globalBreaker.mu.Unlock()
|
||
|
|
globalBreaker.failures = 0
|
||
|
|
globalBreaker.openUntil = time.Time{}
|
||
|
|
}
|
||
|
|
|
||
|
|
func recordBreakerFailure() {
|
||
|
|
globalBreaker.mu.Lock()
|
||
|
|
defer globalBreaker.mu.Unlock()
|
||
|
|
globalBreaker.failures++
|
||
|
|
if globalBreaker.failures >= breakerFailureThreshold {
|
||
|
|
globalBreaker.openUntil = time.Now().Add(breakerCooldown)
|
||
|
|
globalBreaker.failures = 0
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// ResetBreakerForTest clears breaker state.
|
||
|
|
func ResetBreakerForTest() {
|
||
|
|
globalBreaker.mu.Lock()
|
||
|
|
defer globalBreaker.mu.Unlock()
|
||
|
|
globalBreaker.failures = 0
|
||
|
|
globalBreaker.openUntil = time.Time{}
|
||
|
|
}
|