Skip to content

EH-003: Implement Circuit Breaker for Cascading Failure Prevention #76

@azaharizaman

Description

@azaharizaman

Overview

Implement circuit breaker pattern with state management (Closed, Open, Half-Open) to prevent cascading failures and enable automatic recovery.

Requirements

  • REQ-016: Rate limiting and DDoS protection
  • REQ-018: Retry mechanisms and connection pooling
  • CON-001: PHP 8.2+, PHPStan level 7

Implementation Checklist

1. CircuitBreakerState Enum

  • Create src/ErrorHandling/CircuitBreaker/CircuitBreakerState.php
  • Define states: CLOSED, OPEN, HALF_OPEN
  • Use PHP 8.2 enum or constants class
  • Add PHPDoc explaining each state

2. CircuitBreakerConfig Class

  • Create src/ErrorHandling/CircuitBreaker/CircuitBreakerConfig.php
  • Properties: failureThreshold, successThreshold, timeout, halfOpenMaxAttempts
  • Default: 5 failures to open, 2 successes to close, 60s timeout
  • Validation in constructor
  • Immutable design (readonly properties or no setters)

3. CircuitBreaker Class

  • Create src/ErrorHandling/CircuitBreaker/CircuitBreaker.php
  • Constructor: __construct(string $name, CircuitBreakerConfig $config, ?StorageInterface $storage = null)
  • Properties: name, state, failureCount, successCount, lastFailureTime
  • Method: execute(callable $operation): mixed
  • Method: getState(): CircuitBreakerState
  • Method: reset(): void - manually reset circuit
  • Method: forceOpen(): void - manually open circuit
  • Implement state machine logic:
    • CLOSED: Execute operation, track failures, open on threshold
    • OPEN: Fail fast, check timeout for half-open transition
    • HALF_OPEN: Test with limited requests, close or reopen based on results

4. State Transition Logic

  • CLOSED → OPEN: When failure count >= threshold
  • OPEN → HALF_OPEN: After timeout period elapsed
  • HALF_OPEN → CLOSED: When success count >= successThreshold
  • HALF_OPEN → OPEN: On any failure during test period
  • Emit events on state transitions
  • Log state changes with context

5. Storage Interface

  • Create src/ErrorHandling/CircuitBreaker/Storage/StorageInterface.php
  • Methods: getState, setState, getFailureCount, incrementFailureCount, resetCounters
  • Support persistence for circuit breaker state
  • Enable distributed circuit breaker (future)

6. InMemory Storage Implementation

  • Create src/ErrorHandling/CircuitBreaker/Storage/InMemoryStorage.php
  • Implement StorageInterface
  • Store state in PHP array (per-process state)
  • Default storage implementation
  • Add unit tests

7. CircuitBreakerRegistry

  • Create src/ErrorHandling/CircuitBreaker/CircuitBreakerRegistry.php
  • Method: get(string $name, ?CircuitBreakerConfig $config = null): CircuitBreaker
  • Singleton per circuit name
  • Support per-driver and per-operation circuit breakers
  • Method: getAllCircuitBreakers(): array
  • Method: reset(string $name): void

8. Health Check Integration

  • Method in CircuitBreaker: setHealthCheck(callable $healthCheck): void
  • Run health check before transitioning from OPEN to HALF_OPEN
  • Configurable health check timeout
  • Health check result influences state transition

9. Events

  • Create src/ErrorHandling/CircuitBreaker/Events/CircuitBreakerEvent.php base event
  • Create CircuitOpenedEvent, CircuitClosedEvent, CircuitHalfOpenedEvent
  • Include circuit name, previous state, new state, timestamp in events
  • Integrate with event dispatcher from Integration API epic

10. Metrics Integration

  • Track: state duration, failure rate, success rate, state transition count
  • Method: getMetrics(): array returning circuit breaker statistics
  • Prepare for integration with Performance Monitoring epic

11. Unit Tests

  • Test state transitions (CLOSED → OPEN → HALF_OPEN → CLOSED)
  • Test fail fast in OPEN state
  • Test timeout-based transition to HALF_OPEN
  • Test success/failure tracking
  • Test manual reset and force open
  • Test storage interface implementations
  • Mock time for deterministic testing

12. Integration Tests

  • Test circuit breaker with real operation failures
  • Test recovery after timeout period
  • Test concurrent access (if applicable)
  • Verify event emission

13. Documentation

  • Create docs/circuit-breaker.md
  • Explain circuit breaker pattern and states
  • Configuration examples
  • Usage examples with operations
  • Troubleshooting guide (why is circuit open?)
  • Best practices (threshold tuning, timeout selection)

Acceptance Criteria

  • Circuit breaker implements all three states correctly
  • State transitions happen based on thresholds and timeouts
  • OPEN state fails fast without executing operation
  • Circuit recovers automatically through HALF_OPEN state
  • Registry manages multiple circuit breakers
  • Events are emitted on state changes
  • Unit tests achieve 95%+ coverage
  • PHPStan reports no errors

Files Created

  • src/ErrorHandling/CircuitBreaker/CircuitBreaker.php
  • src/ErrorHandling/CircuitBreaker/CircuitBreakerState.php
  • src/ErrorHandling/CircuitBreaker/CircuitBreakerConfig.php
  • src/ErrorHandling/CircuitBreaker/CircuitBreakerRegistry.php
  • src/ErrorHandling/CircuitBreaker/Storage/*.php (interface + in-memory)
  • src/ErrorHandling/CircuitBreaker/Events/*.php
  • tests/ErrorHandling/CircuitBreaker/ (comprehensive tests)
  • docs/circuit-breaker.md

Dependencies

  • Task EH-001 (Exception Hierarchy)
  • Task EH-002 (Retry Framework)

Related

  • Plan: plan/feature-exception-handling.md (Task 3)
  • PRD: docs/prd/11-EXCEPTION-HANDLING-EPIC.md

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions