Race between pool requests in Guzzle

主宰稳场 提交于 2019-12-24 08:59:39

问题


I'm doing mutiple api concurrent requests using guzzle Pool. Everything's working fine.

But I want to stop/avoid all requests if any of the requests responded. That is, I want to do some race between the requests. Is it possible using Guzzle in laravel?

Here's what I've done so far:

        $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 is an array of URIs


回答1:


I don't think it is possible with a current implementation of the Guzzle Pool. The only thing you can possibly do with it is to exit; in the fulfilled function:

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

In this case it will still send all the requests, but immediately exit the script on the fastest response.

Without the Pool you can use GuzzleHttp\Promise\any or GuzzleHttp\Promise\some helper functions:

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();

From the docs for GuzzleHttp\Promise\some($count, $promises):

Initiate a competitive race between multiple promises or values (values will become immediately fulfilled promises).

When count amount of promises have been fulfilled, the returned promise is fulfilled with an array that contains the fulfillment values of the winners in order of resolution.

This promise is rejected with a {@see GuzzleHttp\Promise\AggregateException} if the number of fulfilled promises is less than the desired $count.

From the docs for GuzzleHttp\Promise\any($promises):

Like some(), with 1 as count. However, if the promise fulfills, the fulfillment value is not an array of 1 but the value directly.



来源:https://stackoverflow.com/questions/49474365/race-between-pool-requests-in-guzzle

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!