проблема
Мы пытаемся выполнять одновременные асинхронные запросы с использованием жужжания. Пройдя несколько ресурсов, вроде этого и этого, мы придумали некоторый код, который будет использоваться ниже. Однако он работает не так, как ожидалось.
Похоже, что Guzzle выполняет эти запросы синхронно, а не async.
ожидание
Только для тестовых целей мы нажимаем внутренний URL-адрес, который делает 5-секундный сон. При параллелизме 10 мы ожидаем, что все 10 запросов будут сначала поставлены в очередь и будут отправляться на сервер почти одновременно, где они будут ждать 5 секунд, и тогда почти все из них будут завершены почти одновременно. Это заставит клиента жужжать получить 10 новых запросов от итератора и так далее.
Код
$iterator = function() {
$index = 0;
while (true) {
$client = new Client(['timeout'=>20]);
$url = 'http://localhost/wait/5' . $index++;
$request = new Request('GET',$url, []);
echo "Queuing $url @ " . (new Carbon())->format('Y-m-d H:i:s') . PHP_EOL;
yield $client
->sendAsync($request)
->then(function(Response $response) use ($request) {
return [$request, $response];
});
}
};
$promise = \GuzzleHttp\Promise\each_limit(
$iterator(),
10, /// concurrency,
function($result, $index) {
/** GuzzleHttp\Psr7\Request $request */
list($request, $response) = $result;
echo (string) $request->getUri() . ' completed '.PHP_EOL;
},
function(RequestException $reason, $index) {
// left empty for brevity
}
);
$promise->wait();
Фактические результаты
Мы находим, что Гузл никогда не делал второй запрос до тех пор, пока первый не будет завершен. и так далее.
Queuing http://localhost/wait/5/1 @ 2017-09-01 17:15:28
Queuing http://localhost/wait/5/2 @ 2017-09-01 17:15:28
Queuing http://localhost/wait/5/3 @ 2017-09-01 17:15:28
Queuing http://localhost/wait/5/4 @ 2017-09-01 17:15:28
Queuing http://localhost/wait/5/5 @ 2017-09-01 17:15:28
Queuing http://localhost/wait/5/6 @ 2017-09-01 17:15:28
Queuing http://localhost/wait/5/7 @ 2017-09-01 17:15:28
Queuing http://localhost/wait/5/8 @ 2017-09-01 17:15:28
Queuing http://localhost/wait/5/9 @ 2017-09-01 17:15:28
Queuing http://localhost/wait/5/10 @ 2017-09-01 17:15:28
http://localhost/wait/5/1 completed
Queuing http://localhost/wait/5/11 @ 2017-09-01 17:15:34
http://localhost/wait/5/2 completed
Queuing http://localhost/wait/5/12 @ 2017-09-01 17:15:39
http://localhost/wait/5/3 completed
Queuing http://localhost/wait/5/13 @ 2017-09-01 17:15:45
http://localhost/wait/5/4 completed
Queuing http://localhost/wait/5/14 @ 2017-09-01 17:15:50
Информация о ОС/версии
- Ubuntu
- PHP/7.1.3
- GuzzleHttp/6.2.1
- локон /7.47.0
Проблема может быть в \GuzzleHttp\Promise\each_limit.., которая, возможно, не инициирует или не разрешает обещание достаточно быстро. Вполне возможно, что мы должны обмануть, что в tick
ИНГ извне.