Guzzle 中的池请求之间的竞赛

Race between pool requests in Guzzle

我正在使用 guzzle 池执行多个 api 并发请求。 一切正常。

但我想 stop/avoid 所有请求,如果有任何请求响应的话。也就是说,我想在请求之间进行一些竞争。是否可以在 laravel 中使用 Guzzle?

这是我目前所做的:

        $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 数组

我认为当前的 Guzzle Pool 实现不可能。你唯一可以用它做的就是 fulfilled 函数中的 exit;

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

在这种情况下,它仍会发送所有请求,但会立即以最快的响应退出脚本。

没有 Pool 你可以使用 GuzzleHttp\Promise\any or 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) 的文档:

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.

来自 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.