tourze/symfony-circuit-breaker-bundle
Lightweight Symfony bundle that adds circuit breaker protection to your services. It prevents cascading failures by detecting failing dependencies and short-circuiting calls until they recover, with simple configuration and seamless integration for resilient PHP applications.
This is a Symfony bundle, not a Laravel package — that framing matters more than anything else at 0.0.1. There is no Laravel service provider, no facade, no config/circuit_breaker.php, and no package auto-discovery. Treat the first hour as reconnaissance rather than installation.
Where to look first, in order:
composer.json — the Symfony framework/http-kernel version constraints. This tells you whether it can coexist with the Symfony components Laravel already ships, and whether it targets a Symfony version newer than Laravel's underlying components.*Bundle.php) and DependencyInjection/ — the Extension and Configuration classes are the real public API. They define the config tree and the service IDs, which is what you actually need to know.The 0.0.1 release notes are only a link to the commit list, so there is no documented surface yet. Read the diff, not the changelog.
First use case: guard one outbound dependency — a payment gateway, shipping-rate lookup, or third-party auth endpoint — where you want to fail fast and serve a degraded response instead of letting slow timeouts cascade. Start with exactly one call site. Do not wrap your whole HTTP client on day one; you want to watch the state transitions and tune thresholds against real traffic before generalizing.
On the Symfony side (if you have a Symfony app or a shared monorepo): register the bundle in config/bundles.php, then configure it under config/packages/. Services are wired through the DI container, so the intended pattern is to inject the breaker (or a decorated client) into the service that makes the outbound call.
On the Laravel side, there are three realistic options:
Port the concept, not the package. The state machine is small — a failure counter, a cooldown timestamp, and a half-open trial. Reimplementing it as a CircuitBreakerManager singleton with a cache-backed store takes an afternoon and gives you Laravel-native config, facades, and testing helpers. For most Laravel teams this is the right call at 0.0.1.
Bridge it. If you want the exact upstream semantics, write a small service provider that registers the Symfony Configuration/Extension output, or hand-wire the breaker class as a singleton. You are now maintaining a compatibility shim across two ecosystems — budget for that.
Decorator wrapper. Whichever route you take, wrap an existing client rather than scattering if ($breaker->isOpen()) checks through controllers. In Laravel, bind the decorated client into the container so call sites are unchanged:
$this->app->bind(PaymentClient::class, fn ($app) =>
new CircuitBreakerClient(
new HttpPaymentClient(),
$app->make(CircuitBreakerManager::class)->for('payments')
)
);
Other patterns worth adopting early:
payments should not be tripped by failures from shipping. Resolve by name from a manager.CircuitOpenException bubbling into a Blade view is not a user experience."tourze/symfony-circuit-breaker-bundle": "0.0.1"), not a caret range. A 0.0.x patch release can and will rename classes.extra.laravel.providers, no auto-discovery, no php artisan vendor:publish. Any tutorial you find assuming a service provider will not apply.Configuration tree; in Laravel, container bindings and an interface (CircuitBreakerStore) you can swap for a fake in tests. If the package's state store isn't already abstracted behind an interface, that is the first thing to wrap.How can I help you explore Laravel packages today?