talentrydev/backoff

2.0.0 2024-05-31 13:30 UTC

This package is auto-updated.

Last update: 2024-08-31 00:35:46 UTC


README

本模块提供了一个重试机制,实现了指数退避和抖动。如果您不熟悉这些概念,请查看以下页面:https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/

我们提供了一个单类,您可以使用如下方式

(new Backoff)
    ->setBackoffStrategy(new ExponentialStrategy(200))
    // Either ExponentialStrategy or ConstantStrategy
    // Default is ExponentialStrategy with 200ms base wait time
    // Every BackoffStrategy must be passed a number of milliseconds that it will
    // use for the initial wait time (or also for further attempts depending on the Strategy)
    
    ->setWaitStrategy(new USleepStrategy())
    // Either USleepStrategy or VoidStrategy (aka dont wait)
    // Default is USleepStrategy
    
    ->setRetryDeciderStrategy(new MaxAttemptStrategy(4))
    // Default is MaxAttemptStrategy with a default of 4 attempts. No other strategy available out of the box
    // Using one or even multiple custom strategies is explained further down
    
    ->setJitterStrategy(new FullJitterStrategy())
    // Either FullJitterStrategy or NoJitterStrategy
    // Default is FullJitterStrategy
    
    // you can pass any callable here
    ->run(
        function () {
            // network operation to external service that might fail
        }
    );

最简单的情况如下所示

(new Backoff())
    ->run(
        function () {
            // network operation to external service that might fail
        }
    );

默认情况下,我们会一直尝试,直到达到最大尝试次数(MaxAttemptStrategy 默认为 4)。如果您想根据不同的逻辑(例如抛出的异常)提前停止尝试,可以传递一个自定义的 RetryDeciderStratey

(new Backoff)
    ->setRetryDeciderStrategy(
        new class implements RetryDeciderStrategy {
            public function shouldRetry(
                int $currentAttempt,
                \Throwable $exception,
                $callableResult = null,
            ): bool {
                // only try again if we receive this kind of exception
                return $exception instanceof NetworkSaturedException;
            }
        }
    )
    ->run(
        function () {
            // network operation to external service that might fail
        }
    );

在上面的例子中,如果条件始终满足,代码可能会无限运行。为了避免这种情况,您可以使用 CompositeStrategy,它允许多个策略同时使用。这样,您可以在检查特定条件的同时,在一定的尝试次数后终止。策略的顺序并不重要,因为我们会在第一个策略失败时立即停止执行。

$customStrategy = new class implements RetryDeciderStrategy {
    public function shouldRetry(
        int $currentAttempt,
        \Throwable $exception,
        $callableResult = null
    ): bool {
        // only try again if we receive this kind of exception
        return $exception instanceof NetworkSaturedException;
    }
};

$retryStrategy = new CompositeStrategy();

$retryStrategy
    ->addStrategy($customStrategy)
    ->addStrategy(new MaxAttemptsStrategy(7));

(new Backoff)
    ->setRetryDeciderStrategy($retryStrategy)
    ->run(
        function () {
            // network operation to external service that might fail
        }
    );

开发

  • 安装 composer 依赖项:make deps
  • 运行测试:make test
  • 运行代码嗅探器:make cs
  • 修复代码嗅探器违规:make csfix