bizkit / circuit-breaker-bundle
Symfony bundle integrating the circuit breaker pattern with Symfony HttpClient.
Package info
github.com/HypeMC/circuit-breaker-bundle
Type:symfony-bundle
pkg:composer/bizkit/circuit-breaker-bundle
Requires
- php: >=8.1
- gabrielanhaia/php-circuit-breaker: ^3.0
- psr/cache: ^3.0
- symfony/config: ^6.4 || ^7.4 || ^8.0
- symfony/dependency-injection: ^6.4 || ^7.4 || ^8.0
- symfony/http-client: ^6.4 || ^7.4 || ^8.0
- symfony/http-kernel: ^6.4 || ^7.4 || ^8.0
Requires (Dev)
- phpunit/phpunit: ^12.5
- symfony/console: ^6.4 || ^7.4 || ^8.0
- symfony/event-dispatcher: ^6.4 || ^7.4 || ^8.0
- symfony/phpunit-bridge: ^8.1
Suggests
- symfony/console: Required to use the circuit-breaker console commands.
- symfony/event-dispatcher: Required to dispatch php-circuit-breaker events through Symfony's event dispatcher.
This package is auto-updated.
Last update: 2026-06-25 22:04:21 UTC
README
BizkitCircuitBreakerBundle integrates
gabrielanhaia/php-circuit-breaker with Symfony HttpClient. It
decorates configured HTTP clients and records request successes or failures in a PSR-6 cache-backed circuit breaker.
Features
-
Symfony HttpClient integration: Decorates the main
http_clientservice and configured scoped HTTP client services. -
Per-client circuit breaker configuration: Configure thresholds, time windows, open/half-open timeouts, and exception behavior for the main client and each scoped client.
-
PSR-6 cache storage: Uses a configured cache pool service as the storage backend for circuit breaker state.
-
Symfony Event Dispatcher integration: Dispatches php-circuit-breaker events through Symfony's event dispatcher when
symfony/event-dispatcheris installed. -
Console commands: Optional commands are available when
symfony/consoleis installed to inspect, force, and clear circuit breaker state.
What Is a Circuit Breaker?
When your application calls an external service such as a payment gateway, email API, or internal HTTP API, that service can become slow or unavailable. Without protection, your application keeps sending requests, piling up timeouts, wasting resources, and degrading user experience.
A circuit breaker monitors failures and automatically stops calling a failing service, giving it time to recover. It works like an electrical circuit breaker: when too many failures occur, the circuit opens and requests fail fast without hitting the remote service.
stateDiagram-v2
[*] --> Closed
Closed --> Open : Failures reach threshold
Open --> HalfOpen : Timeout expires
HalfOpen --> Closed : Success threshold met
HalfOpen --> Open : Any failure
Loading
| State | Behavior |
|---|---|
| Closed | Normal operation. Requests pass through. Failures are counted. |
| Open | Requests are blocked immediately. No calls reach the remote service. |
| Half-Open | Probe requests are allowed through to test whether the service recovered. |
Requirements
- PHP 8.1 or higher
- Symfony 6.4, Symfony 7.4, or higher
gabrielanhaia/php-circuit-breaker3.0 or higher
Installation
Require the bundle using Composer:
composer require bizkit/circuit-breaker-bundle
If your project doesn't use Symfony Flex, enable the bundle in config/bundles.php:
return [ Bizkit\CircuitBreakerBundle\BizkitCircuitBreakerBundle::class => ['all' => true], ];
Create a configuration file under config/packages/bizkit_circuit_breaker.yaml:
bizkit_circuit_breaker: # Circuit breaker configuration for the main Symfony HttpClient service. http_client: # Service ID of the PSR-6 cache pool used to store circuit breaker state. storage: cache.app failure_threshold: 5 success_threshold: 1 time_window: 20 open_timeout: 30 half_open_timeout: 20 exceptions_enabled: false # Circuit breaker configuration for scoped Symfony HttpClient services. scoped_http_clients: api.client: # Service ID of the PSR-6 cache pool used to store circuit breaker state. storage: cache.app failure_threshold: 3 success_threshold: 1 time_window: 20 open_timeout: 60 half_open_timeout: 20 exceptions_enabled: false
The storage value must be the service ID of a PSR-6 cache pool, for example cache.app. A client without a configured
storage value is not decorated.
Usage
Once configured, use Symfony HttpClient normally. The bundle decorates the configured services during container compilation:
use Symfony\Contracts\HttpClient\HttpClientInterface; final class ApiClient { public function __construct( private readonly HttpClientInterface $client, ) { } public function fetch(): string { return $this->client ->request('GET', 'https://example.com/api') ->getContent(); } }
Successful responses record successes when the response body completes. Server errors (5xx) and transport errors
record failures. When the circuit is open and exceptions_enabled is false, the decorated client returns a synthetic
503 response. When exceptions_enabled is true, the underlying circuit breaker throws its open-circuit exception.
Scoped HTTP Clients
Use scoped_http_clients when you want different circuit breaker settings per HTTP client service:
framework: http_client: scoped_clients: api.client: base_uri: 'https://example.com/api/' bizkit_circuit_breaker: scoped_http_clients: api.client: storage: cache.app failure_threshold: 3
Scoped clients do not inherit settings from http_client. Each configured scoped client uses its own defaults unless
values are provided explicitly.
Console Commands
When symfony/console is installed, the bundle registers these commands. The command set follows the same operational
shape as gabrielanhaia/laravel-circuit-breaker: inspect
state, force a state, and clear overrides.
php bin/console bizkit:circuit-breaker:status http_client php bin/console bizkit:circuit-breaker:force http_client open --ttl=60 php bin/console bizkit:circuit-breaker:clear http_client
Use the configured service name as the command argument. For the main client, use http_client. For scoped clients, use
the scoped client service ID.
Versioning
This project follows Semantic Versioning 2.0.0.
Reporting Issues
Use the project's issue tracker to report bugs or request improvements.
License
See the LICENSE file for details (MIT).