PHP implementation of circuit breaker pattern.

Overview

What is php-circuit-breaker

Build Status

A component helping you gracefully handle outages and timeouts of external services (usually remote, 3rd party services).

It is a library providing extremely easy to use circuit breaker component. It does not require external dependencies and it has default storage implementations for APC and Memcached but can be extended multiple ways.

Frameworks support

This library does not require any particular PHP framework, all you need is PHP 5.3 or higher.

Symfony 2

If you are using Symfony 2 framework you should use php-circuit-breaker-bundle. It is a bundle i have created to wrap up php-circuit-breaker and integrate it with Symfony 2 components and Dependency Injection.

Other Frameworks

If you are using other frameworks and you would like to use php-circuit-breaker please let me know and we can try to build up an open source integration just like the one for Symfony 2.

Motivation & Benefits

  • Allow application to detect failures and adapt its behaviour without human intervention.
  • Increase robustness of services by addinf fail-safe functionality into modules.

Installation

You can download sources and use them with your autoloader or you can use composer in which case all you nees is a require like this:

"require": {
    "ejsmont-artur/php-circuit-breaker": "*"
},

After that you should update composer dependencies and you are good to go.

Use Case - Non-Critical Feature

  • Your application has an Non-Critical Feature like: user tracking, stats, recommendations etc
  • The optional feature uses remote service that causes outages of your application.
  • You want to keep applicaton and core processes available when "Non-Critical Feature" fails.

Code of your application could look something like:

    $factory = new Ejsmont\CircuitBreaker\Factory();
    $circuitBreaker = $factory->getSingleApcInstance(30, 300);

    $userProfile = null;
    if( $circuitBreaker->isAvailable("UserProfileService") ){
        try{
            $userProfile = $userProfileService->loadProfileOrWhatever();
            $circuitBreaker->reportSuccess("UserProfileService");
        }catch( UserProfileServiceConnectionException $e ){
            // network failed - report it as failure
            $circuitBreaker->reportFailure("UserProfileService");
        }catch( Exception $e ){
            // something went wrong but it is not service's fault, dont report as failure
        }
    }
    if( $userProfile === null ){
        // for example, show 'System maintenance, you cant login now.' message
        // but still let people buy as logged out customers.
    }

Use Case - Payment Gateway

  • Web application depends on third party service (for example a payment gateway).
  • Web application needs to keep track when 3rd party service is unavailable.
  • Application can not become slow/unavailable, it has to tell user that features are limited or just hide them.
  • Application uses circuit breaker before checkout page rendering and if particular payment gateway is unavailable payment option is hidden from the user.

As you can see that is a very powerful concept of selectively disabling feautres at runtime but still allowing the core business processes to be uninterrupted.

Backend talking to the payment service could look like this:

    $factory = new Ejsmont\CircuitBreaker\Factory();
    $circuitBreaker = $factory->getSingleApcInstance(30, 300);

    try{
        // try to process the payment
        // then tell circuit breaker that it went well
        $circuitBreaker->reportSuccess("PaymentOptionOne");
    }catch( SomePaymentConnectionException $e ){
        // If you get network error report it as failure
        $circuitBreaker->reportFailure("PaymentOptionOne");
    }catch( Exception $e ){
        // in case of your own error handle it however it makes sense but
        // dont tell circuit breaker it was 3rd party service failure
    }

Since you are recording failed and successful operations you can now use them in the front end as well to hide payment options that are failing.

Frontend rendering the available payment options could look like this:

    $factory = new Ejsmont\CircuitBreaker\Factory();
    $circuitBreaker = $factory->getSingleApcInstance(30, 300);

    if ($circuitBreaker->isAvailable("PaymentOptionOne")) {
        // display the option
    }

Features

  • Track multiple services through a single Circuit Breaker instance.
  • Pluggable backend adapters, provided APC and Memcached by default.
  • Customisable service thresholds. You can define how many failures are necessary for service to be considered down.
  • Customisable retry timeout. You do not want to disable the service forever. After provided timeout circuit breaker will allow a single process to attempt

Performance Impact

Overhead of the Circuit Breaker is negligible.

APC implementation takes roughly 0.0002s to perform isAvailable() and then reportSuccess() or reportFailure().

Memcache adapter is in range of 0.0005s when talking to the local memcached process.

The only potential performance impact is network connection time. If you chose to use remote memcached server or implement your own custom StorageAdapter.

Running tests

  • Tests are run via PHPUnit It is assumed to be installed via PEAR.
  • Tests can be ran using phpunit alone or via ant build targets.
  • The "ci" target generate code coverage repor, "phpunit" target does not.

You can run all tests by any of the following:

ant
ant phpunit
ant ci

You can run selected test case by running:

cd tests
phpunit Unit/Ejsmont/CircuitBreaker/Storage/Adapter/DummyAdapterTest.php

Details

Before documentation gets updated you can read more on the concept of circuit breaker and its implementation on my blog http://artur.ejsmont.org/blog/circuit-breaker

Some implementation details has changed but the core logic is still the same.

Author

You might also like...
Php-rpc-server - JSON RPC server implementation for PHP.

JSON RPC Server implementation for PHP. The json-rpc is a very simple protocol. You can see this by reading the protocol specification. This library i

A pure PHP implementation of the open Language Server Protocol. Provides static code analysis for PHP for any IDE.
A pure PHP implementation of the open Language Server Protocol. Provides static code analysis for PHP for any IDE.

A pure PHP implementation of the open Language Server Protocol. Provides static code analysis for PHP for any IDE.

Implementation of the Token Bucket algorithm in PHP.

Token Bucket This is a threadsafe implementation of the Token Bucket algorithm in PHP. You can use a token bucket to limit an usage rate for a resourc

A PHP implementation of the Unleash protocol aka Feature Flags in GitLab.

A PHP implementation of the Unleash protocol aka Feature Flags in GitLab. This implementation conforms to the official Unleash standards and implement

An implementation of the Minecraft: Bedrock Edition protocol in PHP

BedrockProtocol An implementation of the Minecraft: Bedrock Edition protocol in PHP This library implements all of the packets in the Minecraft: Bedro

PHP Implementation of PASERK

PASERK (PHP) Platform Agnostic SERialized Keys. Requires PHP 7.1 or newer. PASERK Specification The PASERK Specification can be found in this reposito

A minimalistic implementation of Promises for PHP

libPromise A minimalistic implementation of Promises for PHP. Installation via DEVirion Install the DEVirion plugin and start your server. This will c

PHP's Promse implementation depends on the Swoole module.

php-promise-swoole PHP's Promse implementation depends on the Swoole module. Promise::allsettled([ /** Timer 调用 */ /** Timer call */

A circular buffer implementation in PHP

Circular Buffer Installation 💡 This is a great place for showing how to install the package, see below: Run $ composer require lctrs/circular-buffer

Comments
  • Adding a new failure while getting isAvailable information

    Adding a new failure while getting isAvailable information

    Hello,

    I had an issue with your project. The isAvailable should remove failures but it reset the time and keep failures. That looks wrong. I guess there is a typo here: https://github.com/ejsmont-artur/php-circuit-breaker/blob/master/src%2FEjsmont%2FCircuitBreaker%2FCore%2FCircuitBreaker.php#L155

    $this->setFailures($serviceName, $failures);
    

    should be

    $this->setFailures($serviceName, 0);
    
    opened by Nek- 0
  • Mysql adapter

    Mysql adapter

    Is there a specific reason why there is no mysql storage adapter? I would like to have a central point where all webservers could store and retrieve their circuit breaker information instead of having it local.

    I noticed another package not supporting this out of the box as well so am curious if this is a bad idea or not.

    opened by MrMoronIV 1
  • Duplication in ArrayDecorator

    Duplication in ArrayDecorator

    /**

    • This file is part of the php-circuit-breaker package.
    • @link https://github.com/ejsmont-artur/php-circuit-breaker
    • @link http://artur.ejsmont.org/blog/circuit-breaker
    • @author Artur Ejsmont *
    • For the full copyright and license information, please view the LICENSE file. */

    namespace Ejsmont\CircuitBreaker\Storage\Decorator;

    use Ejsmont\CircuitBreaker\Storage\StorageInterface;

    /**

    • This file is part of the php-circuit-breaker package.
    • @link https://github.com/ejsmont-artur/php-circuit-breaker
    • @link http://artur.ejsmont.org/blog/circuit-breaker
    • @author Artur Ejsmont *
    • For the full copyright and license information, please view the LICENSE file. */

    namespace Ejsmont\CircuitBreaker\Storage\Decorator;

    use Ejsmont\CircuitBreaker\Storage\StorageInterface; use Ejsmont\CircuitBreaker\Storage\StorageException;

    opened by wbits 0
  • Storage does not support atomic operations

    Storage does not support atomic operations

    The interface for storage: https://github.com/ejsmont-artur/php-circuit-breaker/blob/master/src/Ejsmont/CircuitBreaker/Storage/StorageInterface.php seems not to support atomic operations. Multiple processes on the same machine can interleave like:

    1. load value X
    2. load value X
    1. store value X+1
    2. store value X+1
    

    so that X+1 is stored instead of X+2 due to this race condition. Are you aware of this? I was planning to integrate a MongoDB storage but with this interface it won't solve the problem.

    opened by giorgiosironi 3
Owner
ArturEjsmont
ArturEjsmont
YL MVC Structure (PHP MVC) is a pattern made in PHP used to implement user interfaces, data, and controlling logic.

YL MVC Structure (PHP MVC) is a pattern made in PHP used to implement user interfaces, data, and controlling logic. It is built based on the combination of ideas from the Yii framework and Laravel framework (yl).

Tan Nguyen 3 Jan 3, 2023
PHP regexp pattern matching Unicode emojis

Emoji pattern This package provides regexp patterns to match Unicode emojis. All forms of emojis are matched, including: Single-character emoji ( ?? )

Incenteev 7 Nov 5, 2022
Easy Repository pattern for PHP Phalcon framework.

Phalcon Repositories Introduction Phalcon Repositories lets you easily build repositories for your Phalcon models, for both SQL and Mongo drivers. PHP

Michele Angioni 18 Oct 7, 2022
Design Pattern Examples in PHP

Design Patterns in PHP This repository is part of the Refactoring.Guru project. It contains PHP examples for all classic GoF design patterns. Each pat

Refactoring.Guru 909 Dec 22, 2022
Implementação do Composite Pattern Utilizando PHP

Composite Pattern - PHP Implementação do Composite Pattern Utilizando PHP Descrição O Composite Pattern é um padrão de projeto estrutural que permite

Anglesson Araújo 1 Jan 2, 2022
Simple repository pattern for laravel, with services!

With repository and service you can separate business logic and query logic, slim controller and DRY. Simple generate repository and service with artisan command, automatically bind interface with repository

Yaz3 27 Jan 1, 2023
this starter kite inspired by laravel & Geo and mvc pattern. it's wrap for Wordpress built in classes.

WordpressStarterKite Introduction Built With Prerequisite Directory Structure Guidelines Getting Started Authors Introduction this starter kite inspir

Omar Hossam Eldin Kandil 7 Aug 24, 2022
Pattern Lab Standard Edition for Twig

Pattern Lab Standard Edition for Twig The Standard Edition for Twig gives developers and designers a clean and stable base from which to develop a Twi

Pattern Lab 102 Oct 24, 2022
Glob-like file and pattern matching utility.

Glob-like file and pattern matching utility.

Chris Kankiewicz 94 Dec 14, 2022
A pure PHP implementation of the MessagePack serialization format / msgpack.org[PHP]

msgpack.php A pure PHP implementation of the MessagePack serialization format. Features Fully compliant with the latest MessagePack specification, inc

Eugene Leonovich 368 Dec 19, 2022