将请求增量添加到Guzzle 5.0池(滚动请求) [英] Incrementally add requests to a Guzzle 5.0 Pool (Rolling Requests)
问题描述
I'm using Guzzle to fetch a large number of URLs in parallel (or asynchronously) using a pool:
$client = new GuzzleHttp\Client([
'base_url' => 'http://httpbin.org',
]);
$requests = [];
for ($i = 0; $i < 8; ++$i) {
$requests[] = $client->createRequest('GET', '/get');
}
$pool = new GuzzleHttp\Pool($client, $requests, [
'pool_size' => 4,
'complete' => function (GuzzleHttp\Event\CompleteEvent $event) {
var_dump($event->getRequest()->getUrl());
},
]);
$pool->wait();
var_dump(count($requests));
如果我在控制台中运行以上命令,它将显示预期的输出:
If I run the above in the console it displays the expected output:
string(22) "http://httpbin.org/get"
string(22) "http://httpbin.org/get"
string(22) "http://httpbin.org/get"
string(22) "http://httpbin.org/get"
string(22) "http://httpbin.org/get"
string(22) "http://httpbin.org/get"
string(22) "http://httpbin.org/get"
string(22) "http://httpbin.org/get"
int(8)
现在,我希望能够根据某些条件向同一池中添加其他请求,我相信这种行为通常称为 rolling [parallel]请求,但是在阅读并重新-阅读文档,我还没弄清楚.这是我尝试过的:
Now, I would like to be able to add additional requests to the same pool based on some condition, I believe this behavior is usually known as rolling [parallel] requests, but after reading and re-reading the documentation I haven't managed to figure it out. Here's something I tried:
$client = new GuzzleHttp\Client([
'base_url' => 'http://httpbin.org',
]);
$requests = [];
for ($i = 0; $i < 8; ++$i) {
$requests[] = $client->createRequest('GET', '/get');
}
$i = 0;
$pool = new GuzzleHttp\Pool($client, $requests, [
'pool_size' => 4,
'complete' => function (GuzzleHttp\Event\CompleteEvent $event) use (&$i, $client, &$requests) {
var_dump($event->getRequest()->getUrl());
if (++$i % 3 == 0) {
$requests[] = $client->createRequest('GET', '/ip');
}
},
]);
$pool->wait();
var_dump(count($requests));
对/get
的每三个请求都应向/ip
添加一个新请求,$requests
数组实际上正在增长(增加到10个元素,而不是预期的11个),但是从未真正执行过这些请求.有没有办法让Guzzle池执行初始化后的请求?
Every third request to /get
should add a new request to /ip
, the $requests
array is actually growing (to 10 elements and not 11 as would be expected) but the requests are never really executed. Is there a way of making a Guzzle pool execute post-initialization requests?
推荐答案
有可能,请在生成器,重试和带有尖嘴的顺序发送.
It is possible, see my comment at the guzzle issue Suggestions to GuzzleHttp\Pool #946 for a full example or this gist for a more in-depth example of a comparison between generator, retry and sequential send with guzzle.
关于您的示例,请参阅我的嵌入式注释:
Regarding your example, see my inline comments:
$client = new GuzzleHttp\Client([
'base_url' => 'http://httpbin.org',
]);
$requests = [];
for ($i = 0; $i < 8; ++$i) {
$requests[] = $client->createRequest('GET', '/get');
}
$generator = new ArrayIterator($requests); // use an iterator instead of an array
$i = 0;
$pool = new GuzzleHttp\Pool($client, $generator, [ // use the iterator in the pool
'pool_size' => 4,
'complete' => function (GuzzleHttp\Event\CompleteEvent $event) use (&$i, $client, &$generator) {
var_dump($event->getRequest()->getUrl());
if (++$i % 3 == 0) {
$generator->append($client->createRequest('GET', '/ip')); // append new requests on the fly
}
},
]);
$pool->wait();
这将产生您的预期输出:
This yields your expected output:
string(22) "http://httpbin.org/get"
string(22) "http://httpbin.org/get"
string(22) "http://httpbin.org/get"
string(22) "http://httpbin.org/get"
string(22) "http://httpbin.org/get"
string(22) "http://httpbin.org/get"
string(22) "http://httpbin.org/get"
string(22) "http://httpbin.org/get"
string(21) "http://httpbin.org/ip"
string(21) "http://httpbin.org/ip"
string(21) "http://httpbin.org/ip"
请注意,请求被附加在末尾 strong>.这与 AbstractRetryableEvent :: retry 的工作方式相反这样会将重试次数压缩在当前队列之间的某个位置,而不是在末尾附加.
Please note, that the requests get appended at the end. This is contrary to the workings of AbstractRetryableEvent::retry which will squeeze the retry somewhere in between the current queue instead of appending it at the end.
这篇关于将请求增量添加到Guzzle 5.0池(滚动请求)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!