Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Fault Tolerance Bundle Laravel Package

bugloos/fault-tolerance-bundle

View on GitHub
Deep Wiki
Context7

Scrutinizer Code Quality Build Status

  • Circuit Breaker Pattern
  • Cache each request that you want and saves in Redis for a specified time
  • Determine static fallback data for while that circuit breaker doesn't allow request to be executed and cache data doesn't exist for the request
composer require bugloos/fault-tolerance-bundle
  • PHP v7.4 or above
  • Symfony v4.4 or above

In microservice architecture, a service usually calls other services to retrieve data, and there is the chance that the downstream service may be down. It may be cause by slow network connection, timeouts, or temporal unavailability. Therefore, retrying calls can solve the issue. However, if there is a severe issue on a particular microservice, then it will be unavailable for a longer time. In such case, the request will be continuously sent to that service, since the client doesn’t have any knowledge about a particular service being down. As a result, the network resources will be exhausted with low performance and bad user experience. Also, the failure of one service might lead to cascading failures throughout the application.

Therefore, you can use the Circuit Breaker Design Pattern to overcome this problem. With the help of this pattern, the client will invoke a remote service through a proxy. This proxy will basically behave as an electrical circuit breaker. So, when the number of failures crosses the threshold number, the circuit breaker trips for a particular time period. Then, all the attempts to invoke the remote service will fail within this timeout period. After the timeout expires, the circuit breaker allows a limited number of test requests to pass through it. If those requests succeed, the circuit breaker resumes back to the normal operation. Otherwise, if there is a failure, the timeout period begins again.

To protect a point of access to remote service, we use the command pattern. Here is how a minimal implementation could look like:

namespace App\Proxy;

use Bugloos\FaultToleranceBundle\Contract\Command;

/**
* All commands must extend Fault Tolerance Bundle's Command
  */
class GetOrderProxyCommand extends Command
{
  private $param1;
  
  private $param2;

  public function __construct($param1, $param2)
  { 
      $this->param1 = $param1;
      $this->param2 = $param2;
  }

  /**
    * This function is called internally by Fault Tolerance Bundle, only if the request is allowed
    *
    * @return mixed
    */
  protected function run()
  {
      # Make an HTTP call
  }
}

This command could be used like this:

use Bugloos\FaultToleranceBundle\Factory\CommandFactoryInterface;
use App\Proxy\GetOrderProxyCommand;

class Service
{
  private CommandFactoryInterface $commandFactory;

  public function __construct(CommandFactoryInterface $commandFactory)
  {
      $this->commandFactory = $commandFactory;
  }

  public function getAvatarUrl()
  {
      $getOrderProxyCommand = $this->commandFactory->getCommand(
          GetOrderProxyCommand::class,
          'param1',
          'param2'
      );
      
      $result = $getOrderProxyCommand->execute();
  }
}

Note: the extra parameters you pass to the factory’s getCommand method are forwarded to the command’s constructor.

Command-specific configurations are merged with the default one on instantiation. “GetOrderProxyCommand” in this case is the command key. By default, it is the same as command’s class, but you can set it yourself by overriding the getCommandKey protected method:

    /**
     * @return string
     */
    protected function getCommandKey()
    {
        return 'CustomCommandKey';
    }

Fault tolerant bundle only works with the command keys. If you have two different commands with the same command key - Fault tolerant will disable and enable requests, as for a single entity. This may be used for grouping commands.

To manage configuration for each command you can use Config object in config protected method in command class:

    /**
     * @return ?Bugloos\FaultToleranceBundle\Config\Config
     */
    protected function config()
    {
        return (new Config())
            ->intervalToHalfOpen(15)
            ->failureRateThreshold(20)
            ->timeWindow(60);
    }

Note: the config you set is merged with the default configs.

Request cache, when enabled, caches command execution result within a single HTTP request, so you don’t have to worry about loading data over network more than needed.

Results are cached per command key per cache key. To define cache key generation logic, implement getCacheKey protected method:

    protected function getCacheKey()
    {
        return 'cache_' . $user;
    }

For a command, you can specify fallback logic, that will be executed in case of a failure, or when the remote service is blocked:

namespace App\Proxy;

use Bugloos\FaultToleranceBundle\Contract\Command;

class GetAvatarUrlProxyCommand extends Command
{

    protected function run()
    {
        # Make an HTTP call
    }
  
    /**
     * When __run__ fails for some reason, or when Fault Tolerant doesn't allow the request in the first place,
     * this function result will be returned instead
     *
     * @return string
     */
    protected function getFallback()
    {
        // we failed getting user's picture, so showing a generic no-photo placeholder instead.
        return 'https://example.com/avatars/fallback-image.jpg';
    }
}

Note: If you want to use logic requiring networking for your fallback, make sure to “wrap” it into a Fault tolerant command of its own

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
besmartand-pro/php-quality-config
sentix/ai-chatbot
terminal42/code-quality-tools
codifyo/ts-generator-bundle
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity