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

Appearance settings

[HttpClient] Not handling timeouts asynchronously #44544

Copy link
Copy link
Closed
@peter17

Description

@peter17
Issue body actions

Symfony version(s) affected

5.4.0

Description

Very often, I use the Symfony HttpClient to perform N requests on N URLs asynchronously. By doing so, the total time to complete the N requests is greatly decreased.

However, the same effect is not observed when the remote server does not respond. For instance, if the timeout is set to 5 seconds, performing 10 requests will take 50 seconds. I would expect it to take about 5 seconds, because the requests are made asynchronously.

I have added a script below to reproduce the issue. Please note that it is also reproduced if HttpClient::create is replaced by CurlHttpClient::create or NativeHttpClient::create. Also, it is not related to Symfony 5.4. I reproduce this with 5.3 and 6.0.

How to reproduce

<?php

use Symfony\Component\HttpClient\HttpClient;
use Symfony\Component\HttpClient\Exception\TimeoutException;
use Symfony\Component\Stopwatch\Stopwatch;

require_once __DIR__.'/vendor/autoload_runtime.php';

$client = HttpClient::create();
$stopwatch = new Stopwatch();

$stopwatch->start('not parallel');
try {
    $client->request('GET', 'http://10.255.255.1', ['timeout' => 5]);
} catch (TimeoutException) {
    echo ".";
}
echo "\n".$stopwatch->stop('not parallel')."\n";

$stopwatch->start('parallel');
$requests = [];
for ($i = 0; $i < 10; $i++) {
    $requests[] = $client->request('GET', 'http://10.255.255.1', ['timeout' => 5]);
}
foreach ($requests as $response) {
    try {
        $response->getContent();
    } catch (TimeoutException) {
        echo ".";
    }
}
echo "\n".$stopwatch->stop('parallel')."\n";

The result is below:

.
default/not parallel: 6.00 MiB - 5008 ms
..........
default/parallel: 6.00 MiB - 50012 ms

The last value, 50 seconds, should be more like 5 seconds if the requests really happened asynchronously.

If I replace the unroutable IP with https://www.google.com I get:

default/not parallel: 6.00 MiB - 205 ms
default/parallel: 6.00 MiB - 108 ms

Possible Solution

@nicolas-grekas do you have an explanation for this behavior? I ask because of your inspiring talk on asynchronous HTTP requests using this component. Would you provide some guidance so I could help fixing this issue? Thanks a lot in advance!

Additional Context

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Morty Proxy This is a proxified and sanitized view of the page, visit original site.