问题
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