[HttpClient] Fix decorating progress info in AsyncResponse
This commit is contained in:
parent
6987862d97
commit
e325f51fe2
@ -2097,7 +2097,7 @@ class FrameworkExtension extends Extension
|
||||
|
||||
$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']);
|
||||
}
|
||||
|
@ -98,6 +98,7 @@ final class HttpClientDataCollector extends DataCollector implements LateDataCol
|
||||
$errorCount = 0;
|
||||
$baseInfo = [
|
||||
'response_headers' => 1,
|
||||
'retry_count' => 1,
|
||||
'redirect_count' => 1,
|
||||
'redirect_url' => 1,
|
||||
'user_data' => 1,
|
||||
@ -152,6 +153,11 @@ final class HttpClientDataCollector extends DataCollector implements LateDataCol
|
||||
$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
|
||||
|
@ -151,6 +151,12 @@ final class AsyncContext
|
||||
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);
|
||||
}
|
||||
|
@ -43,6 +43,13 @@ final class AsyncResponse implements ResponseInterface, StreamableInterface
|
||||
{
|
||||
$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) {
|
||||
|
@ -66,7 +66,6 @@ class RetryableHttpClient implements HttpClientInterface
|
||||
}
|
||||
} 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
|
||||
@ -91,8 +90,6 @@ class RetryableHttpClient implements HttpClientInterface
|
||||
}
|
||||
}
|
||||
} elseif ($chunk->isFirst()) {
|
||||
$context->setInfo('retry_count', $retryCount);
|
||||
|
||||
if (false === $shouldRetry = $this->strategy->shouldRetry($context, null, null)) {
|
||||
$context->passthru();
|
||||
yield $chunk;
|
||||
@ -138,6 +135,7 @@ class RetryableHttpClient implements HttpClientInterface
|
||||
'delay' => $delay,
|
||||
]);
|
||||
|
||||
$context->setInfo('retry_count', $retryCount);
|
||||
$context->replaceRequest($method, $url, $options);
|
||||
$context->pause($delay / 1000);
|
||||
|
||||
|
@ -263,4 +263,23 @@ class AsyncDecoratorTraitTest extends NativeHttpClientTest
|
||||
|
||||
$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);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user