我使用Guzzle使用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));
如果我在控制台中运行上面的内容,它会显示预期的输出:
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)
现在,我希望能够根据某些条件向同一个池添加其他请求,我相信这种行为通常称为滚动[并行]请求,但在阅读并重新启动后 - 阅读我无法解决的文档。这是我尝试过的东西:
$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池执行初始化后的请求?
答案 0 :(得分:3)
有可能,请参阅我在guzzle issue Suggestions to GuzzleHttp\Pool #946上的评论获取完整示例或这个要点,以获得generator, retry and sequential send with guzzle之间比较的更深入的示例。
关于您的示例,请参阅我的内联评论:
$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();
这会产生您的预期输出:
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"
请注意,请求最后会附加 。这与AbstractRetryableEvent::retry的工作方式相反,后者将在当前队列之间的某处挤压重试,而不是在最后附加它。