【问题标题】:Incrementally add requests to a Guzzle 5.0 Pool (Rolling Requests)将请求增量添加到 Guzzle 5.0 池(滚动请求)
【发布时间】:2015-03-22 04:59:42
【问题描述】:

我正在使用 Guzzle 使用 pool 并行(或异步)获取大量 URL:

$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 池执行初始化后请求?

【问题讨论】:

标签: php curl iterator guzzle


【解决方案1】:

有可能,请参阅我在guzzle issue Suggestions to GuzzleHttp\Pool #946 上的评论以获取完整示例,或者查看此要点以获取更深入的generator, retry and sequential send with guzzle 之间的比较示例。

关于您的示例,请参阅我的内联 cmets:

$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"

请注意,请求会附加在末尾​​strong>。这与AbstractRetryableEvent::retry 的工作方式相反,后者将在当前队列之间的某处挤压重试,而不是将其附加到末尾。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-07-09
    • 2017-01-13
    • 2021-11-30
    • 2012-12-01
    • 2016-06-30
    • 2014-06-15
    • 1970-01-01
    • 2018-09-03
    相关资源
    最近更新 更多