Add per-host circuit breaker with three-state machine

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
This commit is contained in:
2026-03-20 14:22:00 +03:00
parent 505c7b8c4f
commit 2ca930236d
3 changed files with 472 additions and 0 deletions

50
circuitbreaker/options.go Normal file
View File

@@ -0,0 +1,50 @@
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
}
}
}