The circuit-breaker package by @algoyounes brings the circuit breaker pattern to Laravel. It tracks failures for a named service and prevents cascading failures when a downstream service is unavailable:
- Three-state circuit tracking: closed, open, and half-open
- Named circuits to isolate state per service
- Lifecycle callbacks (i.e.,
onOpen,onSuccess) - Guzzle middleware integration via
X-Circuit-Keyheader - And more...
Circuit State Callbacks
Each service gets its own named circuit. You can attach callbacks to respond when the circuit changes state or when a call succeeds or fails:
$circuit = $this->circuitManager->forService('payment-service'); $circuit->onOpen(function (CircuitTransition $transition) { Log::warning('Payment service circuit opened', [ 'state' => $transition->getState(), ]);}); $circuit->onSuccess(function (CircuitResult $result, CircuitTransition $transition) { // Called when a wrapped call succeeds}); $circuit->onFailure(function (CircuitResult $result, CircuitTransition $transition) { // Called when a wrapped call fails});
Each callback is triggered by a specific event: for example, onOpen runs when the circuit transitions to the open state (blocking calls due to failures), while onSuccess is triggered after a successful wrapped call. The service-name key isolates state per service, letting you track different external dependencies independently.
Running Operations
Once a circuit is configured, wrap your service calls with run(). The circuit breaker handles whether to allow, block, or test the call based on the current state:
$circuit->run(function () { return Http::post('https://payments.example.com/charge', $payload);});
You can also use the CircuitManager directly to skip setting up a CircuitBuilder instance:
$this->circuitManager->run('payment-service', function () { return Http::post('https://payments.example.com/charge', $payload);});
Guzzle Middleware
If your project uses Guzzle directly, the package includes middleware that reads a X-Circuit-Key request header to identify which circuit to apply:
use AlgoYounes\CircuitBreaker\Middleware\GuzzleMiddleware;use GuzzleHttp\Client;use GuzzleHttp\HandlerStack; $stack = HandlerStack::create();$stack->push(GuzzleMiddleware::create()); $client = new Client(['handler' => $stack]); $response = $client->get('https://api.example.com', [ 'headers' => [ 'X-Circuit-Key' => 'external-api', ],]);
You can learn more about this package on GitHub at algoyounes/circuit-breaker.