Implements circuit breaker as a RoundTripper middleware: - Closed → Open after consecutive failure threshold - Open → HalfOpen after configurable duration - HalfOpen → Closed on success, back to Open on failure - Per-host tracking via sync.Map for independent endpoint isolation
51 lines
1.2 KiB
Go
51 lines
1.2 KiB
Go
package circuitbreaker
|
|
|
|
import "time"
|
|
|
|
type options struct {
|
|
failureThreshold int // consecutive failures to trip
|
|
openDuration time.Duration // how long to stay open before half-open
|
|
halfOpenMax int // max concurrent requests in half-open
|
|
}
|
|
|
|
func defaults() options {
|
|
return options{
|
|
failureThreshold: 5,
|
|
openDuration: 30 * time.Second,
|
|
halfOpenMax: 1,
|
|
}
|
|
}
|
|
|
|
// Option configures a Breaker.
|
|
type Option func(*options)
|
|
|
|
// WithFailureThreshold sets the number of consecutive failures required to
|
|
// trip the breaker from Closed to Open. Default is 5.
|
|
func WithFailureThreshold(n int) Option {
|
|
return func(o *options) {
|
|
if n > 0 {
|
|
o.failureThreshold = n
|
|
}
|
|
}
|
|
}
|
|
|
|
// WithOpenDuration sets how long the breaker stays in the Open state before
|
|
// transitioning to HalfOpen. Default is 30s.
|
|
func WithOpenDuration(d time.Duration) Option {
|
|
return func(o *options) {
|
|
if d > 0 {
|
|
o.openDuration = d
|
|
}
|
|
}
|
|
}
|
|
|
|
// WithHalfOpenMax sets the maximum number of concurrent probe requests
|
|
// allowed while the breaker is in the HalfOpen state. Default is 1.
|
|
func WithHalfOpenMax(n int) Option {
|
|
return func(o *options) {
|
|
if n > 0 {
|
|
o.halfOpenMax = n
|
|
}
|
|
}
|
|
}
|