Implement Circuit Breakers for Resilient External Service Calls

Implement Circuit Breakers for Resilient External Service Calls

Use the Circuit Breaker pattern to handle failures in external service calls gracefully. This prevents cascading failures and improves system resilience.

use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;

class CircuitBreaker
{
    private $failureThreshold = 3;
    private $resetTimeout = 30;
    private $lastFailureTime;
    private $failureCount = 0;

    public function call(callable $function)
    {
        if ($this->isOpen()) {
            throw new Exception('Circuit is open');
        }

        try {
            $result = $function();
            $this->reset();
            return $result;
        } catch (Exception $e) {
            $this->recordFailure();
            throw $e;
        }
    }

    private function isOpen()
    {
        if ($this->failureCount >= $this->failureThreshold) {
            $timeSinceLastFailure = time() - $this->lastFailureTime;
            if ($timeSinceLastFailure <= $this->resetTimeout) {
                return true;
            }
            $this->reset();
        }
        return false;
    }

    private function recordFailure()
    {
        $this->failureCount++;
        $this->lastFailureTime = time();
    }

    private function reset()
    {
        $this->failureCount = 0;
        $this->lastFailureTime = null;
    }
}

// Usage
$circuitBreaker = new CircuitBreaker();
try {
    $result = $circuitBreaker->call(function() {
        $client = new Client();
        return $client->get('http://api.example.com');
    });
} catch (Exception $e) {
    // Handle the exception
}
← Back to Tips List