A resilient PHP library that allows to safely make calls to external services
MIT License
This library is compatible with PHP 7.2.5+.
composer require prestashop/circuit-breaker
By default, Circuit Breaker use the Symfony Http Client library, and all the client options are described in the official documentation.
For retro-compatibility, we let you use Guzzle Client instead of Symfony Http Client. To use Guzzle, you need to set the Guzzle client with setClient()
of the settings factory, like this example below:
use PrestaShop\CircuitBreaker\SimpleCircuitBreakerFactory;
use PrestaShop\CircuitBreaker\FactorySettings;
use PrestaShop\CircuitBreaker\Client\GuzzleClient
$circuitBreakerFactory = new SimpleCircuitBreakerFactory();
$factorySettings = new FactorySettings(2, 0.1, 10);
$factorySettings->setClient(new GuzzleHttpClient());
$circuitBreaker = $circuitBreakerFactory->create($factorySettings);
Be aware, that the client options depend on the client implementation you choose!
For the Guzzle implementation, the Client options are described in the HttpGuzzle documentation.
You can use the factory to create a simple circuit breaker.
By default, you need to define 3 parameters for the circuit breaker:
The fallback callback will be used if the distant service is unreachable when the Circuit Breaker is Open (means "is used" if the service is unreachable).
You'd better return the same type of response expected from your distant call.
use PrestaShop\CircuitBreaker\SimpleCircuitBreakerFactory;
use PrestaShop\CircuitBreaker\FactorySettings;
$circuitBreakerFactory = new SimpleCircuitBreakerFactory();
$circuitBreaker = $circuitBreakerFactory->create(new FactorySettings(2, 0.1, 10));
$fallbackResponse = function () {
return '{}';
};
$response = $circuitBreaker->call('https://api.domain.com', [], $fallbackResponse);
If you don't specify any fallback, by default the circuit breaker will return an empty string.
use PrestaShop\CircuitBreaker\SimpleCircuitBreakerFactory;
use PrestaShop\CircuitBreaker\FactorySettings;
$circuitBreakerFactory = new SimpleCircuitBreakerFactory();
$circuitBreaker = $circuitBreakerFactory->create(new FactorySettings(2, 0.1, 10));
$response = $circuitBreaker->call('https://unreacheable.api.domain.com', []); // $response == ''
You can also define the client options (or even set your own client if you prefer).
use PrestaShop\CircuitBreaker\SimpleCircuitBreakerFactory;
use PrestaShop\CircuitBreaker\FactorySettings;
$circuitBreakerFactory = new SimpleCircuitBreakerFactory();
$settings = new FactorySettings(2, 0.1, 10);
$settings->setClientOptions(['method' => 'POST']);
$circuitBreaker = $circuitBreakerFactory->create($settings);
$response = $circuitBreaker->call('https://api.domain.com/create/user', ['body' => ['firstname' => 'John', 'lastname' => 'Doe']]);
If you need more control on your circuit breaker, you should use the AdvancedCircuitBreaker
which manages more features:
SimpleArray
so if you want to "cache" the fact that your service is unreachable you should use a persistent storage;use Doctrine\Common\Cache\FilesystemCache;
use PrestaShop\CircuitBreaker\AdvancedCircuitBreakerFactory;
use PrestaShop\CircuitBreaker\FactorySettings;
use PrestaShop\CircuitBreaker\Storage\DoctrineCache;
$circuitBreakerFactory = new AdvancedCircuitBreakerFactory();
$settings = new FactorySettings(2, 0.1, 60); //60 seconds threshold
//Once the circuit breaker is open, the fallback response will be returned instantly during the next 60 seconds
//Since the state is persisted even other requests/processes will be aware that the circuit breaker is open
$doctrineCache = new FilesystemCache(_PS_CACHE_DIR_ . '/addons_category');
$storage = new DoctrineCache($doctrineCache);
$settings->setStorage($storage);
$circuitBreaker = $circuitBreakerFactory->create($settings);
$response = $circuitBreaker->call('https://unreachable.api.domain.com/create/user', []);
composer test
composer cs-fix && composer phpcb && composer psalm && composer phpcs
We also use PHPQA to check the Code quality during the CI management of the contributions.
If you want to use it (using Docker):
docker run --rm -u $UID -v $(pwd):/app eko3alpha/docker-phpqa --report --ignoredDirs vendor,tests
If you want to use it (using Composer):
composer global require edgedesign/phpqa=v1.20.0 --update-no-dev
phpqa --report --ignoredDirs vendor,tests