Skip to content
Advertisement

How to get the fastest response from Guzzle async http client in PHP

I want to use Guzzle to send HTTP requests to multiple endpoints and I want to use the response that comes in first, rather than waiting for all requests to complete.

My code:

    $client = new GuzzleHttpClient();

    $p1 = $client->requestAsync('GET', 'slow.host');
    $p2 = $client->requestAsync('GET', 'fast.host');

    $any = GuzzleHttpPromiseany([$p1, $p2]);
    $response = $any->wait();

I was expecting that as soon as either of the promises ($p1, $p2) gets resolved, I would get a response, however that’s not how it works with Guzzle. Guzzle will always wait for $p1 to either resolve or reject, even if it takes forever.

From the example above, if the slow.host takes 10 seconds to send a response, and the fast.host takes 1 second to send a response, I would have to wait 10 seconds anyway. I would get the response from fast.host only in case slow.host fails completely (promise gets rejected, no such host, etc).

How do I get the fastest response immediately and ignore the rest?

Advertisement

Answer

The solution is to cancel remaining requests when the first response is received.

// Create your promises here.
// All the promises must use the same guzzle client!
$promises = create_requests(); 

$any = GuzzleHttpPromiseany($promises);

// when data is received from any of the requests:
$any->then(function() use ($promises) {
    // cancel all other requests without waiting for them to fulfill or reject
    foreach ($promises as $promise) {
        $promise->cancel();
    }
});

try {
    // this actually fires all the requests
    $data = $any->wait();
} catch (Exception $e) {
    // Exception will be thrown if ALL requests fail
    // Handle exception here
}
User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement