From 127affb3e84bb0076dbbe36ba0df559297843adb Mon Sep 17 00:00:00 2001 From: Aleksandr Denisyuk Date: Wed, 3 Feb 2021 16:15:06 +0300 Subject: [PATCH] Added docs --- docs/index.md | 268 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 268 insertions(+) create mode 100644 docs/index.md diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..3325e35 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,268 @@ +# Documentation + +- [Configure backoff](#configure-backoff) +- [Enable jitter](#enable-jitter) +- [Use factory](#use-factory) +- [Sleep with backoff](#sleep-with-backoff) +- [Retry for exceptions](#retry-for-exceptions) +- [Handle limited attempts](#handle-limited-attempts) + +## Configure backoff + +Configure base time, cap time and max attempts. Base time is the time for calculating a Backoff algorithm, cap time is the limitation of calculations for base time, max attempts is the limit of call a backoff time generate. Cap time and max attempts are not required. By default cap time is 60 seconds and max attempts is `INF`. + +```php +setCapTime($capTime) + ->setMaxAttempts($maxAttempts) + ->build() +; + +$backoff = new Backoff($strategy, $config); +``` + +Also you must choose a strategy for generating the backoff time. Available are strategies such as constant, exponential, linear and decorrelation. Then instance the Backoff with configured a strategy and a config. + +```php +/** @var DurationInterface $backoffTime */ +$backoffTime = $backoff->generate($attempt = 4); + +// float(16000) +$backoffTime->toMilliseconds(); +``` + +Backoff generates duration time which based on base time and choices strategy. As a result, you can work with such values of time as a second, millisecond, microsecond and nanosecond. + +## Enable jitter + +Enabled jitter allows to add an noise for a backoff time. This is necessary in order to make the generation of the backoff time unlike each other. + +```php +setJitter(new EqualJitter()) + ->build() +; +``` + +You can use [EqualJitter](https://github.com/Orangesoft-Development/backoff/blob/main/src/Jitter/EqualJitter.php) or [FullJitter](https://github.com/Orangesoft-Development/backoff/blob/main/src/Jitter/FullJitter.php). By default jitter is disabled. + +## Use factory + +To easiest way to instance a Backoff is use a backoff factory. This makes configuring and instantiating the Backoff easier. Just configure base time, cap time, max attempts and pass them to the factory method: + +```php +getExponentialEqualJitterBackoff($baseTime, $capTime, $maxAttempts); +``` + +The same can be done by directly instantiating the Backoff. Cap time and max attempts are not required in the backoff factory. + +```php +$baseTime = new Milliseconds(1000); + +/** + * @var LinearFullJitterBackoff $backoff + */ +$backoff = new LinearFullJitterBackoff($baseTime); +``` + +The following the backoff factories are available: + +- [ConstantBackoff](https://github.com/Orangesoft-Development/backoff/blob/main/src/Factory/ConstantBackoff.php) +- [ConstantFullJitterBackoff](https://github.com/Orangesoft-Development/backoff/blob/main/src/Factory/ConstantFullJitterBackoff.php) +- [ConstantEqualJitterBackoff](https://github.com/Orangesoft-Development/backoff/blob/main/src/Factory/ConstantEqualJitterBackoff.php) +- [DecorrelationJitterBackoff](https://github.com/Orangesoft-Development/backoff/blob/main/src/Factory/DecorrelationJitterBackoff.php) +- [ExponentialBackoff](https://github.com/Orangesoft-Development/backoff/blob/main/src/Factory/ExponentialBackoff.php) +- [ExponentialFullJitterBackoff](https://github.com/Orangesoft-Development/backoff/blob/main/src/Factory/ExponentialFullJitterBackoff.php) +- [ExponentialEqualJitterBackoff](https://github.com/Orangesoft-Development/backoff/blob/main/src/Factory/ExponentialEqualJitterBackoff.php) +- [LinearBackoff](https://github.com/Orangesoft-Development/backoff/blob/main/src/Factory/LinearBackoff.php) +- [LinearFullJitterBackoff](https://github.com/Orangesoft-Development/backoff/blob/main/src/Factory/LinearFullJitterBackoff.php) +- [LinearEqualJitterBackoff](https://github.com/Orangesoft-Development/backoff/blob/main/src/Factory/LinearEqualJitterBackoff.php) + +## Sleep with backoff + +The main purpose of Backoff is that to pause certain parts of the code for a while. This can be achieved by using a Sleeper. Just instance the Sleeper with some Backoff instance: + +```php +sleep($attempt = 4); +``` + +The exact same effect can be obtained if immediately instance the Sleeper with definitely strategy: + +```php +$baseTime = new Milliseconds(1000); + +$sleeper = new ExponentialSleeper($baseTime); + +// usleep(16000000); +$sleeper->sleep($attempt = 4); +``` + +The Sleeper falls asleep with microsecond precision. + +## Retry for exceptions + +You can retry to any exceptions and put a backoff time before the next call but before it you must configure a retry tool where must to set max attempts, a sleeper and a exception classifier. By default max attempts is 5, the sleeper is disabled and the exception classifier catch all exceptions. See below how configure the retry tool: + +```php +setMaxAttempts(5) + ->setSleeper($sleeper) + ->setExceptionClassifier($exceptionClassifier) + ->build() +; +``` + +The retry tool interface is very similar to `call_user_func_array()` in that its method `call()` also accepts a callable and args. + +```php +/** + * @param int $min + * @param int $max + * + * @return int + * + * @throws \RuntimeException + */ +$callback = function (int $min, int $max): int { + $random = mt_rand($min, $max); + + if (0 === $random % 2) { + throw new \RuntimeException(); + } + + return $random; +}; + +$args = [5, 10]; + +$retry->call($callback, $args); +``` + +Retry will try to call the callable with args equal to the number set in max attempts in the config and it will put a backoff time each times for current attempt. + +## Handle limited attempts + +For a Backoff you can set max attempts and when this number is exceeded, a LimitedAttemptsException will be thrown: + +```php +generate($attempt = 10); +} catch (LimitedAttemptsException $e) { + // ... +} +``` + +It works exactly the same for a Sleeper: + +```php +$sleeper = new Sleeper($backoff); + +try { + for ($i = 0; $i < 10; $i++) { + $sleeper->sleep($i); + } +} catch (LimitedAttemptsException $e) { + // ... +} +``` + +For a Retry you can set the max attempts to `PHP_INT_MAX` to disable max attempts for a retry tool and turn on count attempts of the Sleeper: + +```php +$retry = (new RetryBuilder()) + ->setMaxAttempts(PHP_INT_MAX) + ->setSleeper($sleeper) + ->build() +; + +try { + $retry->call(function () { + throw new \RuntimeException(); + }); +} catch (LimitedAttemptsException $e) { + // ... +} +``` + +By default max attempts of the retry tool is 5. To disable it, you need to set the largest number that supports PHP.