Инкрементно добавлять запросы в пул Guzzle 5.0 (Rolling Requests)

Я использую Guzzle для извлечения большого количества 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 выполнять запросы после инициализации?

1

Решение

Возможно, см. Мой комментарий на Проблема с жадностью Предложения для GuzzleHttp \ Pool # 946 для полного примера или этой сути для более глубокого примера сравнения между генератор, повтор и последовательная отправка с жадным.

Что касается вашего примера, смотрите мои встроенные комментарии:

$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 :: повторная попытка который будет сжимать повторную попытку где-то посередине между текущей очередью, а не добавлять ее в конце.

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]