Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[HttpClient] Not handling timeouts asynchronously #44544

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 our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
peter17 opened this issue Dec 9, 2021 · 1 comment
Closed

[HttpClient] Not handling timeouts asynchronously #44544

peter17 opened this issue Dec 9, 2021 · 1 comment

Comments

@peter17
Copy link
Contributor

peter17 commented Dec 9, 2021

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

@nicolas-grekas
Copy link
Member

Thanks for the report and the reproducer. Fixed in #44571

nicolas-grekas added a commit that referenced this issue Dec 11, 2021
… requests (nicolas-grekas)

This PR was merged into the 4.4 branch.

Discussion
----------

[HttpClient] Don't reset timeout counter when initializing requests

| Q             | A
| ------------- | ---
| Branch?       | 4.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | Fix #44544
| License       | MIT
| Doc PR        | -

Same as #42896 but on initialize.

Commits
-------

8f3bdeb [HttpClient] Don't reset timeout counter when initializing requests
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants