Skip to content

Commit 37cddd7

Browse files
feature #50240 [HttpClient] Add max_retries option to RetryableHttpClient (danielburger1337)
This PR was squashed before being merged into the 6.4 branch. Discussion ---------- [HttpClient] Add `max_retries` option to `RetryableHttpClient` | Q | A | ------------- | --- | Branch? | 6.4 | Bug fix? | no | New feature? | yes | Deprecations? | no | Tickets | N/A | License | MIT | Doc PR | symfony/symfony-docs#18288 Added a `max_retries` option to RetryableHttpClient that allows the user to configure the RetryableHttpClient on a per request level, which is especially useful when `retry_failed` was configured for the global `http_client` service. ```php <?php use Symfony\Component\HttpClient\HttpClient; use Symfony\Component\HttpClient\RetryableHttpClient; $client = HttpClient::create(); $client = new RetryableHttpClient($client, null, 3); $client->request('GET', '/foo-bar', [ 'max_retries' => 1 // 0 disables retrying ]); // $client = $client->withOptions(['max_retries' => 1]); ``` Commits ------- 496ba59b4f [HttpClient] Add `max_retries` option to `RetryableHttpClient`
2 parents 668f10f + 70f0012 commit 37cddd7

File tree

3 files changed

+55
-3
lines changed

3 files changed

+55
-3
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
6.4
5+
---
6+
7+
* Add `max_retries` option to `RetryableHttpClient` to adjust the retry logic on a per request level
8+
49
6.3
510
---
611

RetryableHttpClient.php

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ public function withOptions(array $options): static
6060
}
6161

6262
$clone = clone $this;
63+
$clone->maxRetries = (int) ($options['max_retries'] ?? $this->maxRetries);
64+
unset($options['max_retries']);
65+
6366
$clone->client = $this->client->withOptions($options);
6467

6568
return $clone;
@@ -71,11 +74,14 @@ public function request(string $method, string $url, array $options = []): Respo
7174
$baseUris = \is_array($baseUris) ? $baseUris : [];
7275
$options = self::shiftBaseUri($options, $baseUris);
7376

74-
if ($this->maxRetries <= 0) {
77+
$maxRetries = (int) ($options['max_retries'] ?? $this->maxRetries);
78+
unset($options['max_retries']);
79+
80+
if ($maxRetries <= 0) {
7581
return new AsyncResponse($this->client, $method, $url, $options);
7682
}
7783

78-
return new AsyncResponse($this->client, $method, $url, $options, function (ChunkInterface $chunk, AsyncContext $context) use ($method, $url, $options, &$baseUris) {
84+
return new AsyncResponse($this->client, $method, $url, $options, function (ChunkInterface $chunk, AsyncContext $context) use ($method, $url, $options, $maxRetries, &$baseUris) {
7985
static $retryCount = 0;
8086
static $content = '';
8187
static $firstChunk;
@@ -152,7 +158,7 @@ public function request(string $method, string $url, array $options = []): Respo
152158
$context->replaceRequest($method, $url, self::shiftBaseUri($options, $baseUris));
153159
$context->pause($delay / 1000);
154160

155-
if ($retryCount >= $this->maxRetries) {
161+
if ($retryCount >= $maxRetries) {
156162
$context->passthru();
157163
}
158164
});

Tests/RetryableHttpClientTest.php

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,4 +344,45 @@ public function testRetryWithMultipleBaseUrisPreservesNonNestedOrder()
344344
self::assertSame(200, $response->getStatusCode());
345345
self::assertSame('http://example.com/d/foo-bar', $response->getInfo('url'));
346346
}
347+
348+
public function testMaxRetriesOption()
349+
{
350+
$client = new RetryableHttpClient(
351+
new MockHttpClient([
352+
new MockResponse('', ['http_code' => 500]),
353+
new MockResponse('', ['http_code' => 502]),
354+
new MockResponse('', ['http_code' => 200]),
355+
]),
356+
new GenericRetryStrategy([500, 502], 0),
357+
3
358+
);
359+
360+
$response = $client->request('GET', 'http://example.com/foo-bar', [
361+
'max_retries' => 1,
362+
]);
363+
364+
self::assertSame(502, $response->getStatusCode());
365+
}
366+
367+
public function testMaxRetriesWithOptions()
368+
{
369+
$client = new RetryableHttpClient(
370+
new MockHttpClient([
371+
new MockResponse('', ['http_code' => 500]),
372+
new MockResponse('', ['http_code' => 502]),
373+
new MockResponse('', ['http_code' => 504]),
374+
new MockResponse('', ['http_code' => 200]),
375+
]),
376+
new GenericRetryStrategy([500, 502, 504], 0),
377+
3
378+
);
379+
380+
$client = $client->withOptions([
381+
'max_retries' => 2,
382+
]);
383+
384+
$response = $client->request('GET', 'http://example.com/foo-bar');
385+
386+
self::assertSame(504, $response->getStatusCode());
387+
}
347388
}

0 commit comments

Comments
 (0)