123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- <?php
- namespace GuzzleHttp;
- use GuzzleHttp\Promise\PromiseInterface;
- use GuzzleHttp\Promise\RejectedPromise;
- use GuzzleHttp\Psr7;
- use Psr\Http\Message\RequestInterface;
- class RetryMiddleware
- {
-
- private $nextHandler;
-
- private $decider;
-
- public function __construct(
- callable $decider,
- callable $nextHandler,
- callable $delay = null
- ) {
- $this->decider = $decider;
- $this->nextHandler = $nextHandler;
- $this->delay = $delay ?: __CLASS__ . '::exponentialDelay';
- }
-
- public static function exponentialDelay($retries)
- {
- return (int) pow(2, $retries - 1);
- }
-
- public function __invoke(RequestInterface $request, array $options)
- {
- if (!isset($options['retries'])) {
- $options['retries'] = 0;
- }
- $fn = $this->nextHandler;
- return $fn($request, $options)
- ->then(
- $this->onFulfilled($request, $options),
- $this->onRejected($request, $options)
- );
- }
- private function onFulfilled(RequestInterface $req, array $options)
- {
- return function ($value) use ($req, $options) {
- if (!call_user_func(
- $this->decider,
- $options['retries'],
- $req,
- $value,
- null
- )) {
- return $value;
- }
- return $this->doRetry($req, $options);
- };
- }
- private function onRejected(RequestInterface $req, array $options)
- {
- return function ($reason) use ($req, $options) {
- if (!call_user_func(
- $this->decider,
- $options['retries'],
- $req,
- null,
- $reason
- )) {
- return new RejectedPromise($reason);
- }
- return $this->doRetry($req, $options);
- };
- }
- private function doRetry(RequestInterface $request, array $options)
- {
- $options['delay'] = call_user_func($this->delay, ++$options['retries']);
- return $this($request, $options);
- }
- }
|