$container
->register($name.'.retryable', RetryableHttpClient::class)
- ->setDecoratedService($name, null, -10) // lower priority than TraceableHttpClient
+ ->setDecoratedService($name, null, 10) // higher priority than TraceableHttpClient
->setArguments([new Reference($name.'.retryable.inner'), $retryStrategy, $options['max_retries'], new Reference('logger')])
->addTag('monolog.logger', ['channel' => 'http_client']);
}
$errorCount = 0;
$baseInfo = [
'response_headers' => 1,
+ 'retry_count' => 1,
'redirect_count' => 1,
'redirect_url' => 1,
'user_data' => 1,
$content = [];
}
+ if (isset($info['retry_count'])) {
+ $content['retries'] = $info['previous_info'];
+ unset($info['previous_info']);
+ }
+
$debugInfo = array_diff_key($info, $baseInfo);
$info = ['info' => $debugInfo] + array_diff_key($info, $debugInfo) + $content;
unset($traces[$i]['info']); // break PHP reference used by TraceableHttpClient
public function replaceRequest(string $method, string $url, array $options = []): ResponseInterface
{
$this->info['previous_info'][] = $this->response->getInfo();
+ if (null !== $onProgress = $options['on_progress'] ?? null) {
+ $thisInfo = &$this->info;
+ $options['on_progress'] = static function (int $dlNow, int $dlSize, array $info) use (&$thisInfo, $onProgress) {
+ $onProgress($dlNow, $dlSize, $thisInfo + $info);
+ };
+ }
return $this->response = $this->client->request($method, $url, ['buffer' => false] + $options);
}
{
$this->client = $client;
$this->shouldBuffer = $options['buffer'] ?? true;
+
+ if (null !== $onProgress = $options['on_progress'] ?? null) {
+ $thisInfo = &$this->info;
+ $options['on_progress'] = static function (int $dlNow, int $dlSize, array $info) use (&$thisInfo, $onProgress) {
+ $onProgress($dlNow, $dlSize, $thisInfo + $info);
+ };
+ }
$this->response = $client->request($method, $url, ['buffer' => false] + $options);
$this->passthru = $passthru;
$this->initializer = static function (self $response) {
}
} catch (TransportExceptionInterface $exception) {
// catch TransportExceptionInterface to send it to the strategy
- $context->setInfo('retry_count', $retryCount);
}
if (null !== $exception) {
// always retry request that fail to resolve DNS
}
}
} elseif ($chunk->isFirst()) {
- $context->setInfo('retry_count', $retryCount);
-
if (false === $shouldRetry = $this->strategy->shouldRetry($context, null, null)) {
$context->passthru();
yield $chunk;
'delay' => $delay,
]);
+ $context->setInfo('retry_count', $retryCount);
$context->replaceRequest($method, $url, $options);
$context->pause($delay / 1000);
$this->assertSame('{"documents":[{"id":"\/json\/1"},{"id":"\/json\/2"},{"id":"\/json\/3"}]}', $content);
}
+
+ public function testInfoPassToDecorator()
+ {
+ $lastInfo = null;
+ $options = ['on_progress' => function (int $dlNow, int $dlSize, array $info) use (&$lastInfo) {
+ $lastInfo = $info;
+ }];
+ $client = $this->getHttpClient(__FUNCTION__, function (ChunkInterface $chunk, AsyncContext $context) use ($options) {
+ $context->setInfo('foo', 'test');
+ $context->getResponse()->cancel();
+ $context->replaceRequest('GET', 'http://localhost:8057/', $options);
+ $context->passthru();
+ });
+
+ $client->request('GET', 'http://localhost:8057')->getContent();
+ $this->assertArrayHasKey('foo', $lastInfo);
+ $this->assertSame('test', $lastInfo['foo']);
+ $this->assertArrayHasKey('previous_info', $lastInfo);
+ }
}