talentrydev / backoff
2.0.0
2024-05-31 13:30 UTC
Requires
- php: ^8.3
Requires (Dev)
- phpunit/phpunit: ^11
- squizlabs/php_codesniffer: ^3.7
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