Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

[HttpClient] Update the concurrent requests section#21004

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
javiereguiluz merged 1 commit intosymfony:6.4fromjaviereguiluz:http_parallel
May 27, 2025
Merged
Changes fromall commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 41 additions & 34 deletionshttp_client.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -1314,65 +1314,72 @@ remaining to do.
Concurrent Requests
-------------------

Thanks to responses being lazy,requestsare always managed concurrently.
On a fast enough network, the following code makes 379 requests inless than
half a second when cURL is used::
Symfony's HTTP client makes asynchronous HTTPrequestsby default. This means
you don't need to configure anything special to send multiple requests inparallel
and process them efficiently.

Here's a practical example that fetches metadata about several Symfony
components from the Packagist API in parallel::

$packages = ['console', 'http-kernel', '...', 'routing', 'yaml'];
$responses = [];
for ($i = 0; $i < 379; ++$i) {
$uri = "https://http2.akamai.com/demo/tile-$i.png";
$responses[] = $client->request('GET', $uri);
foreach ($packages as $package) {
$uri = sprintf('https://repo.packagist.org/p2/symfony/%s.json', $package);
// send all requests concurrently (they won't block until response content is read)
$responses[$package] = $client->request('GET', $uri);
}

foreach ($responses as $response) {
$content = $response->getContent();
// ...
$results = [];
// iterate through the responses and read their content
foreach ($responses as $package => $response) {
// process response data somehow ...
$results[$package] = $response->toArray();
}

As you canreadin the first"for"loop,requests are issuedbutare not consumed
yet. That'sthetrick when concurrency isdesired: requests should be sent
first and be read later on. This will allow the client to monitor all pending
requests while your code waits for a specific one, as done in each iteration of
the above "foreach" loop.
As you cansee, the requests are sentin the first loop, buttheir responses
aren't consumed untilthesecond one. This isthe key to achieving parallel and
concurrent execution: dispatch all requests first, and read them later.
This allows the client to handle all pending responses efficiently while your
code waits only when necessary.

.. note::

The maximum number of concurrent requeststhat you can perform depends on
the resources of your machine(e.g.your operating systemmay limit the
number of simultaneous reads of the file that stores the certificates
file). Make yourrequests in batches to avoid these issues.
The maximum number of concurrent requestsdepends on your system's resources
(e.g.the operating systemmight limit the number of simultaneous connections
or access to certificate files). To avoid hitting these limits, consider
processingrequests in batches.

Multiplexing Responses
~~~~~~~~~~~~~~~~~~~~~~

If you look again at the snippet above, responses are read in requests' order.
But maybe the 2nd response came back before the 1st? Fully asynchronous operations
require being able to deal with the responses in whatever order they come back.
In the previous example, responses are read in the same order as the requests
were sent. However, it's possible that, for instance, the second response arrives
before the first. To handle such cases efficiently, you need fully asynchronous
processing, which allows responses to be handled in whatever order they arrive.

In order to do so, the
:method:`Symfony\\Contracts\\HttpClient\\HttpClientInterface::stream`
acceptsa list of responses to monitor. As mentioned
To achieve this, the
:method:`Symfony\\Contracts\\HttpClient\\HttpClientInterface::stream` method
can be used to monitora list of responses. As mentioned
:ref:`previously <http-client-streaming-responses>`, this method yields response
chunks as they arrivefrom the network.By replacingthe"foreach" in the
snippet withthis one, the code becomes fully async::
chunks assoon asthey arriveover the network.Replacingthestandard ``foreach``
loop withthe following version enables true asynchronous behavior::

foreach ($client->stream($responses) as $response => $chunk) {
if ($chunk->isFirst()) {
//headers of$response just arrived
// $response->getHeaders() is nowanon-blocking call
//the$response headers just arrived
// $response->getHeaders() is now non-blocking
} elseif ($chunk->isLast()) {
// the fullcontent of$responsejust completed
// $response->getContent() is nowanon-blocking call
// the full $responsebody has been received
// $response->getContent() is now non-blocking
} else {
// $chunk->getContent() will return a piece
// of the response body that just arrived
// $chunk->getContent() returns a piece of the body that just arrived
}
}

.. tip::

Use the ``user_data`` optioncombined with ``$response->getInfo('user_data')``
totrack the identity of the responses in your foreach loops.
Use the ``user_data`` optionalong with ``$response->getInfo('user_data')``
toidentify each response during streaming.

Dealing with Network Timeouts
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand Down

[8]ページ先頭

©2009-2025 Movatter.jp