public function onComplete(AbstractTransferEvent $event) { $request = $event->getRequest(); $retries = (int) $request->getConfig()->get('retries'); if ($retries >= $this->maxRetries) { return; } $filterFn = $this->filter; if (call_user_func_array($filterFn, array($retries, $event))) { $delayFn = $this->delayFn; $sleepFn = $this->sleepFn; call_user_func_array($sleepFn, array(call_user_func_array($delayFn, array($retries, $event)), $event)); $request->getConfig()->set('retries', ++$retries); $event->intercept($event->getClient()->send($request)); } }
/** * @param AbstractTransferEvent $event * @throws RotatingProxySubscriberException * @return void */ public function evaluateResult(AbstractTransferEvent $event) { $request = $event->getRequest(); if ($event instanceof ErrorEvent) { $exception = $event->getException(); if ($exception !== null) { do { if ($exception instanceof NoProxiesLeftException) { throw $exception; } $exception = $exception->getPrevious(); } while ($exception !== null); } } $requestId = $request->getConfig()->get(self::$REQUEST_CONFIG_KEY); if ($requestId === null) { return; // Question: What about caches? A cached response might be served so that no proxy was used. // SOLUTION: simply return without exception. // throw new RotatingProxySubscriberException("Config key '".self::$REQUEST_CONFIG_KEY."' not found in request config - this shouldn't happen..."); } if (!array_key_exists($requestId, $this->requestId2ProxyMap)) { // This method really should only be called once, because it determines the result of the proxy request // if it's called multiple times, something is probably wrong. A possible scenario: // Client has a RotatingProxySubscriber and an additional function attached to the complete event that checks wether the // response was logically correct (e.g. contained the right json format) and throws an exception if not. // In that case, this method (evaluateResult) would be called twice: one time in the complete event and the next time // after the exception was thrown (which results in an error event being emitted). // SOLUTION: This can be solved by giving this RotatingProxySubscriber a lower priority so that is called last // Question: Does this introduce problems with ->retry() calls, e.g. is only the last call counted? // Answer: No - see RotatingProxySubscriberTest::test_integration_RetryingRequestsShouldIncreaseFailesAccordingly() $msg = "Request with id '{$requestId}' not found - it was probably already processed. Make sure not to pass on multiple events for the same request. This might be influenced by the event priority."; throw new RotatingProxySubscriberException($msg, $event->getRequest()); } $proxy = $this->requestId2ProxyMap[$requestId]; unset($this->requestId2ProxyMap[$requestId]); $proxy->requested(); // increase request count if ($proxy->evaluate($event)) { $proxy->succeeded(); } else { $proxy->failed(); } }