Problem
Wir versuchen, gleichzeitige asynchrone Anfragen mit guzzle durchzuführen. Nachdem Sie ein paar Ressourcen durchgegangen sind, z Das Und Das, haben wir uns einen Code ausgedacht, der unten geteilt wird. Allerdings funktioniert es nicht wie erwartet.
Es sieht so aus, als würde Guzzle diese Anfrage eher synchron als asynchron ausführen.
Erwartung
Nur zu Testzwecken treffen wir auf eine interne URL, die einen 5-Sekunden-Schlaf ausführt. Bei einer Parallelität von 10 erwarten wir, dass zunächst alle 10 Anfragen in die Warteschlange gestellt und an den Server gesendet werden fast gleichzeitig, wo sie 5 Sekunden warten und dann fast alle werden fast gleichzeitig fertig sein. Was den Guzzle-Client dazu bringen würde, 10 neue Anfragen vom Iterator entgegenzunehmen und so weiter.
Code
$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();
Tatsächliche Ergebnisse
Wir stellen fest, dass Guzzle nie eine zweite Anfrage gestellt hat, bis die erste fertig ist. usw.
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
Betriebssystem-/Versionsinformationen
- Ubuntu
- PHP/7.1.3
- GuzzleHttp/6.2.1
- curl/7.47.0
Das Problem könnte bei \GuzzleHttp\Promise\each_limit .. liegen, was das Promise vielleicht nicht schnell genug initiiert oder auflöst. Es kann sein, dass wir das austricksen müssen tick
nach außen gehen.