bug #35120 [HttpClient] fix scheduling pending NativeResponse (nicolas-grekas)
This PR was merged into the 4.3 branch.
Discussion
----------
[HttpClient] fix scheduling pending NativeResponse
| Q | A
| ------------- | ---
| Branch? | 4.3
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | -
| License | MIT
| Doc PR | -
There must be one pending list per `ResponseStream` instance.
Currently, we start unrelated responses and this can lead to broken iterators when the unrelated response throws because it is a 3/4/5xx.
Commits
-------
a90a6c9c48
[HttpClient] fix scheduling pending NativeResponse
This commit is contained in:
commit
f3d8fd2521
@ -11,8 +11,6 @@
|
||||
|
||||
namespace Symfony\Component\HttpClient\Internal;
|
||||
|
||||
use Symfony\Component\HttpClient\Response\NativeResponse;
|
||||
|
||||
/**
|
||||
* Internal representation of the native client's state.
|
||||
*
|
||||
@ -24,8 +22,6 @@ final class NativeClientState extends ClientState
|
||||
{
|
||||
/** @var int */
|
||||
public $id;
|
||||
/** @var NativeResponse[] */
|
||||
public $pendingResponses = [];
|
||||
/** @var int */
|
||||
public $maxHostConnections = PHP_INT_MAX;
|
||||
/** @var int */
|
||||
|
@ -209,11 +209,7 @@ final class NativeResponse implements ResponseInterface
|
||||
$runningResponses[$i] = [$response->multi, []];
|
||||
}
|
||||
|
||||
if (null === $response->remaining) {
|
||||
$response->multi->pendingResponses[] = $response;
|
||||
} else {
|
||||
$runningResponses[$i][1][$response->id] = $response;
|
||||
}
|
||||
|
||||
if (null === $response->buffer) {
|
||||
// Response already completed
|
||||
@ -315,25 +311,30 @@ final class NativeResponse implements ResponseInterface
|
||||
return;
|
||||
}
|
||||
|
||||
if ($multi->pendingResponses && \count($multi->handles) < $multi->maxHostConnections) {
|
||||
// Create empty activity lists to tell ResponseTrait::stream() we still have pending requests
|
||||
foreach ($responses as $i => $response) {
|
||||
if (null === $response->remaining && null !== $response->buffer) {
|
||||
$multi->handlesActivity[$i] = [];
|
||||
}
|
||||
}
|
||||
|
||||
if (\count($multi->handles) >= $multi->maxHostConnections) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Open the next pending request - this is a blocking operation so we do only one of them
|
||||
/** @var self $response */
|
||||
$response = array_shift($multi->pendingResponses);
|
||||
foreach ($responses as $i => $response) {
|
||||
if (null === $response->remaining && null !== $response->buffer) {
|
||||
$response->open();
|
||||
$responses[$response->id] = $response;
|
||||
$multi->sleep = false;
|
||||
self::perform($response->multi);
|
||||
self::perform($multi);
|
||||
|
||||
if (null !== $response->handle) {
|
||||
$multi->handles[] = $response->handle;
|
||||
}
|
||||
}
|
||||
|
||||
if ($multi->pendingResponses) {
|
||||
// Create empty activity list to tell ResponseTrait::stream() we still have pending requests
|
||||
$response = $multi->pendingResponses[0];
|
||||
$responses[$response->id] = $response;
|
||||
$multi->handlesActivity[$response->id] = [];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user