A back-off strategy interface for retrying operations.

Overview

EventSauce BackOff

This library provides an interface for encapsulated back-off strategies.

composer require eventsauce/backoff

Leveraging the back-off strategies

A back-off strategy is applied in side a piece of code that retries a certain task.

<?php

use EventSauce\BackOff\BackOffStrategy;

class BusinessLogic
{
    public function __construct(
        private ExternalDependency $dependency,
        private BackOffStrategy $backOff,
    ) {}

    public function performAction(): void
    {
        $tries = 0;

        start:
        try {
            ++$tries;
            $this->dependency->actionThatMayFail();
        } catch (Throwable $throwable) {
            $this->backOff->backOff($tries, $throwable);
            goto start;
        }
    }
}

Exponential back-off

A well-known back-off strategy is exponential back-off, which is the default provided strategy.

sleep = initial_delay * (base ^ (number_of_tries - 1)
<?php

use EventSauce\BackOff\ExponentialBackOffStrategy;

$backOff = new ExponentialBackOffStrategy(
    100000, // initial delay in microseconds, 0.1 seconds
    15, //  max number of tries
    2500000, // (optional) max delay in microseconds, default 2.5 seconds
    2.0, // (optional) base to control the growth factor, default 2.0
);

$businessLogic = new BusinessLogic(new ExternalDependency(), $backOff);

try {
    $businessLogic->performAction();
} catch (Throwable $throwable) {
    // handle the throwable
}

Fibonacci back-off

The Fibonacci back-off strategy increases the back-off based on the fibonacci sequence.

sleep = initial_delay * fibonacci(number_of_tries)
<?php

use EventSauce\BackOff\FibonacciBackOffStrategy;

$backOff = new FibonacciBackOffStrategy(
    100000, // initial delay in microseconds, 0.1 seconds
    15, // max number of tries
    2500000, // (optional) max delay in microseconds, default 2.5 seconds
);

$businessLogic = new BusinessLogic(new ExternalDependency(), $backOff);

try {
    $businessLogic->performAction();
} catch (Throwable $throwable) {
    // handle the throwable
}

Linear back-off

The linear back-off strategy increases the back-off time linearly.

sleep = initial_delay * number_of_tries
<?php

use EventSauce\BackOff\LinearBackOffStrategy;

$backOff = new LinearBackOffStrategy(
    100000, // initial delay in microseconds, 0.1 seconds
    15, // max number of tries
    2500000, // (optional) max delay in microseconds, default 2.5 seconds
);

$businessLogic = new BusinessLogic(new ExternalDependency(), $backOff);

try {
    $businessLogic->performAction();
} catch (Throwable $throwable) {
    // handle the throwable
}

Jitter

When many clients are forced to retry, having deterministic interval can cause many of these clients to retry at the same time. Adding randomness to the mix ensures retrying clients are scattered across time. The randomness ensures that it is less likely for the clients to all retry at the same time.

Using Jitter

Every strategy that sleeps accepted a EventSauce\BackOff\Jitter\Jitter implementation.

use EventSauce\BackOff\ExponentialBackOffStrategy;
use EventSauce\BackOff\FibonacciBackOffStrategy;
use EventSauce\BackOff\LinearBackOffStrategy;

$exponential = new ExponentialBackOffStrategy(100000, 25, jitter: $jitter);
$fibonacci = new FibonacciBackOffStrategy(100000, 25, jitter: $jitter);
$linear = new LinearBackOffStrategy(100000, 25, jitter: $jitter);

Full Jitter

full jitter

The full jitter uses a randomized value from 0 to the initial calculated sleep time.

sleep = number_between(0, sleep)
use EventSauce\BackOff\Jitter\FullJitter;
$jitter = new FullJitter();

Half Jitter

half jitter

The full jitter uses a randomized value from half the initial sleep to the full initial sleep time.

sleep = sleep / 2 + number_between(0 , sleep / 2)
use EventSauce\BackOff\Jitter\HalfJitter;
$jitter = new HalfJitter();

Scattered Jitter

scattered jitter

The scattered jitter uses a range in across which it's scatter the resulting values. To illustrate, here are a few examples:

Range Min Max
0.25 75% 125%
0.5 50% 150%
0.1 90% 110%
jittered = sleep * range
base = sleep - jittered
sleep = base + number_between(0 , jittered * 2)
use EventSauce\BackOff\Jitter\ScatteredJitter;
$jitter = new ScatteredJitter($range = 0.5);

Design rationale

Unlike other exponential back-off libraries, this library doesn't run the operation you want to retry. This makes the design of the package very simple. It also doesn't impose any limitations on the surround code.

You can retry based on a return value:

use EventSauce\BackOff\BackOffStrategy;

function action(Client $client, BackOffStrategy $backOff): void
{
    $tries = 0;
    start:
    $tries++;
    $response = $client->doSomething();
    
    if ($response == SomeParticular::VALUE) {
        $backOff->backOff($tries, new LogicException('Exhausted back-off'));
        goto start;
    }
}

You can retry on a specific exception type:

use EventSauce\BackOff\BackOffStrategy;

function action(Client $client, BackOffStrategy $backOff): void
{
    $tries = 0;
    start:
    $tries++;
    
    try {
        $client->doSomething();
    } catch (SpecificException $exception) {
        $backOff->backOff($tries, $exception);
        goto start;
    }
}

The choice is yours. Enjoy!


PS: yes, those were a lot of goto statements, deal with it 😎

You might also like...
A PocketMine-MP plugin that replaces a block to another block when breaks, then back to the original block after a certain time

BlockReplacer A PocketMine-MP plugin that replaces a block to another block when breaks, then back to the original block after a certain time How to I

Mapa avaliativo de back end I
Mapa avaliativo de back end I

2021 | Aluno: BRUNO J. VASCONCELOS BOA SORTE | RA: 20061660-5

Resources back-end for the Nextcloud CalDAV server

Calendar Resource Management This app enables the 🗓️ Calendar App to work with resources and rooms Installation Place this app in nextcloud/apps/ You

Tcc realizado na Etec de Guaianazes (2021),onde eu fui o back-end e Vinicius de Almeida foi o front-end.

TCC-Facilita+ Todos os arquivos do projeto de TCC (Facilita+) da Etec de Guaianases realizado em 2021 1° Para utilizar os arquivos,primeiro será nesce

A @laravel based RAD platform for back-office applications, admin/user panels, and dashboards.
A @laravel based RAD platform for back-office applications, admin/user panels, and dashboards.

For the full documentation, visit orchid.software. Introduction Orchid is a free Laravel package that abstracts standard business logic and allows cod

Back the fun of reading - PHP Port for Arc90′s Readability

PHP Readability Library If you want to use an up-to-date version of this algorithm,check this newer project: https://github.com/andreskrey/readability

PHP class for convert KA letters to LAT and back

Kautilities PHP class for convert KA letters to LAT and back Installation Install this package through Composer. Edit your project's composer.json fil

A tool that allows to quickly export data from Magento 1 and Magento 2 store and import it back into Magento 2

Simple Import / Export tool A tool that allows to quickly export data from Magento 1 and Magento 2 store and import it back into Magento 2. Table data

Safely break down arrays or objects, and put them back together in new shapes.

traverse/reshape traverse() and reshape() are companion functions that safely break down arrays or objects and put them back together in new shapes. t

Comments
  • Use case

    Use case

    Looks interesting, it will be helpful if more explanation of its use case. Is it to handle concurrency issue when commands are executed on the same aggregate?

    opened by dilab 2
Owner
EventSauce
An event sourcing library for PHP.
EventSauce
🚀 An open source multiplayer space strategy game.

Badges Introduction The game story takes place in a virtual galaxy where randomly generated planets produce various raw materials which can be used by

Galaxy of Drones Online 192 Dec 25, 2022
Learn how to run WordPress with Docker. Read about our experiences and start off with an easy boilerplate.

Hi! We're Dan and Jay. We're a two person team with a passion for open source products. We created Server Side Up to help share what we learn. Find us

Server Side Up 7 Sep 17, 2022
A text-based, persistent browser-based strategy game (PBBG) in a fantasy war setting

Note: OpenDominion is still in development. Some features of the game have not been implemented yet. Introduction OpenDominion is a free and open-sour

null 180 Dec 28, 2022
Foundation 3 Framework for Magento 1.7. Foundation styles and libraries. Magento Responsive theme. Off-canvas Left-Right sidebar columns for mobile.

Magento Foundation 3 Framework Zurb Foundation 3 framework for Magento 1.7. Magento Foundation 3 Version 1.3.0. Demo page: http://magendation.internet

Nando Boronat 62 Apr 1, 2022
MeowOfDuty - An open source multiplayer space strategy game

The game story takes place in a virtual galaxy where randomly generated planets produce various raw materials which can be used by the Players to develop their infrastructure and fleet. In addition, players may trade with the Earth or engage in battles, so beyond various military arrangements, economic decisions should be taken as well.

@stux 3 Jun 27, 2022
Simplifies GST calculation and operations

Simplifies GST calculation and operations Installation You can install the package via composer: composer require gaurangsharma/gst-calculator Usage u

Gaurang Sharma 1 Oct 21, 2021
Learning about - Basic HTML & CSS, JSON, XML, Session & Cookies, CRUD Operations in Php using MySQL and Create MVC from scratch

This Project is based on course CSC 3215. Learning about - Basic HTML & CSS, JSON, XML, Session & Cookies, CRUD Operations in Php using MySQL and Create MVC (Model–View–Controller) from scratch. Just learning about web technologies, Not focusing on UI (Bootstrap or other 3rd-Party UI libraries or frameworks).

Alvi Hasan 5 Sep 21, 2022
StringBuffer is a PHP class providing operations for efficient string buffering

StringBuffer is a PHP class providing operations for efficient string buffering

null 1 May 26, 2022
The Pantheon CLI — a standalone utility for performing operations on the Pantheon Platform

terminus : Pantheon's Command-Line Interface Status About Terminus is Pantheon's Command Line Interface (CLI), providing at least equivalent functiona

Pantheon 290 Dec 26, 2022
The plugin allows to execute math operations in the server or console.

General The plugin allows to execute math operations in the server or console with /calculator command Arithmetic Operators List of supported arithmet

NhanAZ's PocketMine-MP Plugins 3 Oct 20, 2022