mirror of
https://github.com/andwati/telecom-platform.git
synced 2026-10-18 11:02:54 +00:00
feat: Add circuit breaker pattern implementation to API server with configurable thresholds and timeout
- Add State enum with Closed, Open, and HalfOpen states and String method - Add CircuitBreaker struct with mutex, state tracking, failure/success counters, and timeout - Add Config struct with FailureThreshold, SuccessThreshold, and Timeout fields - Add NewCircuitBreaker constructor with Config parameter - Add DefaultConfig with 5 failure threshold, 2 success threshold, and 60 second timeout
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
package circuitbreaker
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// State represents the state of the circuit breaker
|
||||
type State int
|
||||
|
||||
const (
|
||||
StateClosed State = iota
|
||||
StateOpen
|
||||
StateHalfOpen
|
||||
)
|
||||
|
||||
func (s State) String() string {
|
||||
switch s {
|
||||
case StateClosed:
|
||||
return "Closed"
|
||||
case StateOpen:
|
||||
return "Open"
|
||||
case StateHalfOpen:
|
||||
return "HalfOpen"
|
||||
default:
|
||||
return "Unknown"
|
||||
}
|
||||
}
|
||||
|
||||
// CircuitBreaker implements the circuit breaker pattern
|
||||
type CircuitBreaker struct {
|
||||
mu sync.Mutex
|
||||
state State
|
||||
failureCount uint
|
||||
failureThreshold uint
|
||||
successThreshold uint
|
||||
timeout time.Duration
|
||||
lastFailureTime time.Time
|
||||
halfOpenSuccesses uint
|
||||
}
|
||||
|
||||
// Config holds the configuration for the circuit breaker
|
||||
type Config struct {
|
||||
FailureThreshold uint
|
||||
SuccessThreshold uint
|
||||
Timeout time.Duration
|
||||
}
|
||||
|
||||
// NewCircuitBreaker creates a new circuit breaker with the given configuration
|
||||
func NewCircuitBreaker(config Config) *CircuitBreaker {
|
||||
return &CircuitBreaker{
|
||||
state: StateClosed,
|
||||
failureThreshold: config.FailureThreshold,
|
||||
successThreshold: config.SuccessThreshold,
|
||||
timeout: config.Timeout,
|
||||
}
|
||||
}
|
||||
|
||||
// DefaultConfig returns a default configuration for the circuit breaker
|
||||
func DefaultConfig() Config {
|
||||
return Config{
|
||||
FailureThreshold: 5,
|
||||
SuccessThreshold: 2,
|
||||
Timeout: 60 * time.Second,
|
||||
}
|
||||
}
|
||||
|
||||
// Execute runs the given function with circuit breaker protection
|
||||
func (cb *CircuitBreaker) Execute(fn func() error) error {
|
||||
cb.mu.Lock()
|
||||
|
||||
// Check if we should attempt to transition from Open to HalfOpen
|
||||
if cb.state == StateOpen && time.Since(cb.lastFailureTime) > cb.timeout {
|
||||
cb.state = StateHalfOpen
|
||||
cb.halfOpenSuccesses = 0
|
||||
}
|
||||
|
||||
// If circuit is open, reject the request
|
||||
if cb.state == StateOpen {
|
||||
cb.mu.Unlock()
|
||||
return errors.New("circuit breaker is open")
|
||||
}
|
||||
|
||||
cb.mu.Unlock()
|
||||
|
||||
// Execute the function
|
||||
err := fn()
|
||||
|
||||
cb.mu.Lock()
|
||||
defer cb.mu.Unlock()
|
||||
|
||||
if err != nil {
|
||||
cb.onFailure()
|
||||
return err
|
||||
}
|
||||
|
||||
cb.onSuccess()
|
||||
return nil
|
||||
}
|
||||
|
||||
// onFailure handles a failed operation
|
||||
func (cb *CircuitBreaker) onFailure() {
|
||||
cb.failureCount++
|
||||
cb.lastFailureTime = time.Now()
|
||||
|
||||
if cb.failureCount >= cb.failureThreshold {
|
||||
cb.state = StateOpen
|
||||
}
|
||||
}
|
||||
|
||||
// onSuccess handles a successful operation
|
||||
func (cb *CircuitBreaker) onSuccess() {
|
||||
if cb.state == StateClosed {
|
||||
cb.failureCount = 0
|
||||
return
|
||||
}
|
||||
|
||||
if cb.state == StateHalfOpen {
|
||||
cb.halfOpenSuccesses++
|
||||
if cb.halfOpenSuccesses >= cb.successThreshold {
|
||||
cb.state = StateClosed
|
||||
cb.failureCount = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// GetState returns the current state of the circuit breaker
|
||||
func (cb *CircuitBreaker) GetState() State {
|
||||
cb.mu.Lock()
|
||||
defer cb.mu.Unlock()
|
||||
return cb.state
|
||||
}
|
||||
|
||||
// Reset resets the circuit breaker to closed state
|
||||
func (cb *CircuitBreaker) Reset() {
|
||||
cb.mu.Lock()
|
||||
defer cb.mu.Unlock()
|
||||
cb.state = StateClosed
|
||||
cb.failureCount = 0
|
||||
cb.halfOpenSuccesses = 0
|
||||
}
|
||||
Reference in New Issue
Block a user