I'm using Guzzle to send a number of requests to an API endpoint, using the Pool
functionality to send these asynchronously and concurrently.
The script looks like this:
use GuzzleHttpClient;
use GuzzleHttpPromise;
use GuzzleHttpPool;
use GuzzleHttpPsr7Request;
use GuzzleHttpExceptionRequestException;
/* Configure logger */
Logger::configure("config/logger.xml");
$logger = Logger::getLogger("console");
/* Configure Guzzle Client */
$client = new Client([
'base_uri' => 'http://my.api/',
'timeout' => 2.0,
'allow_redirects' => false,
]);
/* Anonymous function (closure) to 'yield' X number of Requests */
$requests = function ($num_requests) {
for ($i = 0; $i < $num_requests; $i++) {
yield new Request('GET', "/MY_UNIQUE_IDENTIFIER/");
}
};
/* Create a Pool for the above requests */
$pool = new Pool($client, $requests(20), [
'concurrency' => 5, // Determine how many requests to send concurrently
'fulfilled' => function ($response, $index) {
$logger->info('$index: ' . $index . ', $response: ' . $response);
},
'rejected' => function ($reason, $index) {
try {
echo $reason;
} catch (Exception $e) {
trigger_error($e->getMessage(), E_USER_WARNING);
}
},
]);
/* Initiate transfers/create a promise */
$promise = $pool->promise();
/* Force the pool of requests to complete */
$promise->wait();
Basically, send 20 requests (5 at a time) to http://my.api/MY_UNIQUE_IDENTIFIER
.
The Pool
appears to work. If I add an echo
to the rejected
requests, I get output like:
#0 /Users/me/guzzle-POC/vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php(149): GuzzleHttpHandlerCurlFactory::createRejection(Object(GuzzleHttpHandlerEasyHandle), Array)
#1 /Users/me/guzzle-POC/vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php(102): GuzzleHttpHandlerCurlFactory::finishError(Object(GuzzleHttpHandlerCurlMultiHandler), Object(GuzzleHttpHandlerEasyHandle), Object(GuzzleHttpHandlerCurlFactory))
#2 /Users/me/guzzle-POC/vendor/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php(181): GuzzleHttpHandlerCurlFactory::finish(Object(GuzzleHttpHandlerCurlMultiHandler), Object(GuzzleHttpHandlerEasyHandle), Object(GuzzleHttpHandlerCurlFactory))
#3 /Users/me/guzzle-POC/vendor/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php(110): GuzzleHttpHandlerCurlMultiHandler->processMessages()
#4 /Users/me/guzzle-POC/vendor/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php(125): GuzzleHttpHandlerCurlMultiHandler->tick()
#5 /Users/me/guzzle-POC/vendor/guzzlehttp/promises/src/Promise.php(246): GuzzleHttpHandlerCurlMultiHandler->execute(true)
#6 /Users/me/guzzle-POC/vendor/guzzlehttp/promises/src/Promise.php(223): GuzzleHttpPromisePromise->invokeWaitFn()
#7 /Users/me/guzzle-POC/vendor/guzzlehttp/promises/src/Promise.php(267): GuzzleHttpPromisePromise->waitIfPending()
#8 /Users/me/guzzle-POC/vendor/guzzlehttp/promises/src/Promise.php(225): GuzzleHttpPromisePromise->invokeWaitList()
#9 /Users/me/guzzle-POC/vendor/guzzlehttp/promises/src/Promise.php(62): GuzzleHttpPromisePromise->waitIfPending()
#10 /Users/me/guzzle-POC/vendor/guzzlehttp/promises/src/EachPromise.php(101): GuzzleHttpPromisePromise->wait()
#11 /Users/me/guzzle-POC/vendor/guzzlehttp/promises/src/Promise.php(246): GuzzleHttpPromiseEachPromise->GuzzleHttpPromise{closure}(true)
#12 /Users/me/guzzle-POC/vendor/guzzlehttp/promises/src/Promise.php(223): GuzzleHttpPromisePromise->invokeWaitFn()
#13 /Users/me/guzzle-POC/vendor/guzzlehttp/promises/src/Promise.php(62): GuzzleHttpPromisePromise->waitIfPending()
#14 /Users/me/guzzle-POC/poc.php(50): GuzzleHttpPromisePromise->wait()
#15 {main}GuzzleHttpExceptionConnectException: cURL error 6: Could not resolve host: my.api (see http://curl.haxx.se/libcurl/c/libcurl-errors.html) in /Users/me/guzzle-POC/vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php:185
The main problem here being #15
, Could not resolve host: my.api
. This is expected behaviour, but I want to catch this exception.
The try/catch
that I've used just doesn't work at all - it catches nothing.
Presumably this is because of the Pool's asynchronous nature, but is it possible to catch these exceptions in any way?
All I want to achieve basically is, if can't resolve; log error and continue with other requests
-type approach.
See Question&Answers more detail:
os