Chris@0: decider = $decider; Chris@0: $this->nextHandler = $nextHandler; Chris@0: $this->delay = $delay ?: __CLASS__ . '::exponentialDelay'; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Default exponential backoff delay function. Chris@0: * Chris@0: * @param $retries Chris@0: * Chris@0: * @return int Chris@0: */ Chris@0: public static function exponentialDelay($retries) Chris@0: { Chris@0: return (int) pow(2, $retries - 1); Chris@0: } Chris@0: Chris@0: /** Chris@0: * @param RequestInterface $request Chris@0: * @param array $options Chris@0: * Chris@0: * @return PromiseInterface Chris@0: */ Chris@0: public function __invoke(RequestInterface $request, array $options) Chris@0: { Chris@0: if (!isset($options['retries'])) { Chris@0: $options['retries'] = 0; Chris@0: } Chris@0: Chris@0: $fn = $this->nextHandler; Chris@0: return $fn($request, $options) Chris@0: ->then( Chris@0: $this->onFulfilled($request, $options), Chris@0: $this->onRejected($request, $options) Chris@0: ); Chris@0: } Chris@0: Chris@0: private function onFulfilled(RequestInterface $req, array $options) Chris@0: { Chris@0: return function ($value) use ($req, $options) { Chris@0: if (!call_user_func( Chris@0: $this->decider, Chris@0: $options['retries'], Chris@0: $req, Chris@0: $value, Chris@0: null Chris@0: )) { Chris@0: return $value; Chris@0: } Chris@0: return $this->doRetry($req, $options, $value); Chris@0: }; Chris@0: } Chris@0: Chris@0: private function onRejected(RequestInterface $req, array $options) Chris@0: { Chris@0: return function ($reason) use ($req, $options) { Chris@0: if (!call_user_func( Chris@0: $this->decider, Chris@0: $options['retries'], Chris@0: $req, Chris@0: null, Chris@0: $reason Chris@0: )) { Chris@0: return \GuzzleHttp\Promise\rejection_for($reason); Chris@0: } Chris@0: return $this->doRetry($req, $options); Chris@0: }; Chris@0: } Chris@0: Chris@0: private function doRetry(RequestInterface $request, array $options, ResponseInterface $response = null) Chris@0: { Chris@0: $options['delay'] = call_user_func($this->delay, ++$options['retries'], $response); Chris@0: Chris@0: return $this($request, $options); Chris@0: } Chris@0: }