Circuit Breaker With Failure Threshold
Trip a circuit breaker after consecutive failures, short-circuiting calls during an open period and probing recovery with a half-open state.
Code
package breaker
import (
"errors"
"sync"
"time"
)
type State int
const (
Closed State = iota
Open
HalfOpen
)
var ErrOpen = errors.New("circuit breaker is open")
type Breaker struct {
mu sync.Mutex
state State
failures int
threshold int
openedAt time.Time
resetTimeout time.Duration
}
func (b *Breaker) Call(fn func() error) error {
b.mu.Lock()
if b.state == Open {
if time.Since(b.openedAt) < b.resetTimeout {
b.mu.Unlock()
return ErrOpen
}
b.state = HalfOpen
}
b.mu.Unlock()
err := fn()
b.mu.Lock()
defer b.mu.Unlock()
if err != nil {
b.failures++
if b.failures >= b.threshold {
b.state = Open
b.openedAt = time.Now()
}
return err
}
b.failures = 0
b.state = Closed
return nil
}Report a problem with this exampleOpens a pre-filled issue on GitHub.