Skip to content

denisyukphp/backoff

Folders and files

NameName
Last commit message
Last commit date

Latest commit

20d7d96 · Nov 19, 2024

History

99 Commits
Sep 9, 2023
Mar 30, 2023
Nov 19, 2024
Nov 19, 2024
Mar 30, 2023
Nov 19, 2024
Mar 30, 2023
Jul 1, 2024
Sep 9, 2023
Sep 9, 2023
Sep 9, 2023
Jul 9, 2024
Nov 19, 2024
Sep 9, 2023
Mar 30, 2023
Jul 1, 2024
Sep 9, 2023

Repository files navigation

BackOff

Build Status Latest Stable Version Packagist PHP Version Support Total Downloads License

Back-off algorithm implementation.

Installation

You can install the latest version via Composer:

composer require orangesoft/backoff

This package requires PHP 8.1 or later.

Quick usage

Configure Orangesoft\BackOff\Retry\Retry::class, any of back-off classes, and Orangesoft\BackOff\Retry\ExceptionClassifier\ExceptionClassifier::class to retry a business logic when an exception is thrown:

<?php

use Orangesoft\BackOff\ExponentialBackOff;
use Orangesoft\BackOff\Duration\Microseconds;
use Orangesoft\BackOff\Retry\ExceptionClassifier\ExceptionClassifier;
use Orangesoft\BackOff\Retry\Retry;

$retry = new Retry(
    maxAttempts: 3,
    backOff: new ExponentialBackOff(
        baseTime: new Microseconds(1_000),
        capTime: new Microseconds(512_000),
        factor: 2.0,
    ),
    exceptionClassifier: new ExceptionClassifier(
        classNames: [
            \RuntimeException::class,
        ],
    ),
);

Use the Orangesoft\BackOff\Retry\Retry::call(callable $callback): mixed method to wrap the business logic and call it with retry functionality:

/** @var int $result */
$result = $retry->call(static function (): int {
    $random = mt_rand(0, 1);
    
    if (0 === $random % 2) {
        throw new \RuntimeException();
    }
    
    return $random;
});

The following back-off strategies are available:

Enable Jitter

Pass the implementation of Orangesoft\BackOff\Jitter\JitterInterface::class to the back-off class and jitter will be enabled:

<?php

use Orangesoft\BackOff\ExponentialBackOff;
use Orangesoft\BackOff\Duration\Microseconds;
use Orangesoft\BackOff\Jitter\EqualJitter;

$backOff = new ExponentialBackOff(
    baseTime: new Microseconds(1_000),
    capTime: new Microseconds(512_000),
    factor: 2.0,
    jitter: new EqualJitter(),
);

for ($i = 1; $i <= 10; $i++) {
    $backOff->backOff(
        attempt: $i,
    );
}

Below you can see the time intervals in microseconds for exponential back-off with a factor of 2.0 and equal jitter, where the base time is 1_000 μs and the cap time is 512_000 μs:

+---------+---------------------------+--------------------+
| attempt | exponential back-off (μs) | equal jitter (μs)  |
+---------+---------------------------+--------------------+
|       1 |                     1_000 |         [0, 1_000] |
|       2 |                     2_000 |     [1_000, 2_000] |
|       3 |                     4_000 |     [2_000, 4_000] |
|       4 |                     8_000 |     [4_000, 8_000] |
|       5 |                    16_000 |    [8_000, 16_000] |
|       6 |                    32_000 |   [16_000, 32_000] |
|       7 |                    64_000 |   [32_000, 64_000] |
|       8 |                   128_000 |  [64_000, 128_000] |
|       9 |                   256_000 | [128_000, 256_000] |
|      10 |                   512_000 | [256_000, 512_000] |
+---------+---------------------------+--------------------+

The following jitters are available:

Read more about Back-Off and Jitter on AWS Architecture Blog.