Гонка между запросами пула в Guzzle

Я делаю несколько одновременных запросов api, используя guzzle Pool. Все работает нормально.

Но я хочу остановить / избежать всех запросов, если какой-либо из запросов ответил. То есть я хочу устроить гонку между запросами. Возможно ли использование Guzzle в laravel?

Вот что я сделал до сих пор:

        $requests = function(array $urls){

                foreach ($urls as $url) {

                    yield new Request('GET', $url);

                }

        };


        $pool = new Pool($client, 
                        $requests($urls),

                        [
                            'concurrency' => 5,
                            'fulfilled' => function($response, $index) use ($urls){

                                echo "<br>Completed ".$urls[$index];

                            },

                            'rejected' => function($reason, $index){

                                echo "Rejected ".$index;


                            },
                        ]);


        $promise = $pool->promise();

        $promise->wait();

$ urls - это массив URI


person Misbah Ahmad    schedule 25.03.2018    source источник


Ответы (1)


Я не думаю, что это возможно с текущей реализацией Guzzle Pool. Единственное, что вы можете с ним сделать, это exit; в функции fulfilled:

'fulfilled' => function($response, $index) use ($urls){
    echo "Completed " . $urls[$index];
    exit;
 },

В этом случае он по-прежнему будет отправлять все запросы, но немедленно выйдет из сценария при самом быстром ответе.

Без пула вы можете использовать GuzzleHttp \ Promise \ any или вспомогательные функции GuzzleHttp \ Promise \ some:

use GuzzleHttp\Client;
use GuzzleHttp\Promise;

$client = new Client(['base_uri' => 'http://site.local/']);

// Initiate each request but do not block
$promises = [
    'delay3' => $client->getAsync('/async/delay3.php'),
    'delay2' => $client->getAsync('/async/delay2.php'),
    'delay1' => $client->getAsync('/async/delay1.php'),
];

//Initiate a competitive race between multiple promises
$promise = Promise\any($promises)->then(
    function (\GuzzleHttp\Psr7\Response $response) {
        echo "Completed: " . $response->getStatusCode() . "\n";
        echo $response->getBody() ."\n";
    },
    function ($reason) {
        echo $reason;
    }
);

$results = $promise->wait();

Из документов для GuzzleHttp\Promise\some($count, $promises):

Инициируйте соревновательную гонку между несколькими обещаниями или ценностями (ценности станут немедленно выполненными обещаниями).

Когда подсчет количества обещаний был выполнен, возвращенное обещание выполняется с помощью массива, который содержит значения выполнения победителей в порядке разрешения.

Это обещание отклоняется с {@see GuzzleHttp \ Promise \ AggregateException}, если количество выполненных обещаний меньше требуемого количества $ count.

Из документации для GuzzleHttp\Promise\any($promises):

Как some (), с 1 как count. Однако, если обещание выполняется, значение выполнения - это не массив из 1, а непосредственно значение.

person zstate    schedule 27.03.2018
comment
Не могли бы вы объяснить, что на самом деле делает какая-либо функция? - person Misbah Ahmad; 27.03.2018
comment
Спасибо за ваш ответ! Кстати, можете дать мне ссылку на обработчик повторных попыток для использования с этим одновременным запросом guzzle - person Misbah Ahmad; 27.03.2018
comment
Вы можете использовать промежуточное ПО для повторных попыток github.com/guzzle/guzzle/blob /master/src/Middleware.php#L155, не уверен, что это то, что вам нужно. - person zstate; 27.03.2018