Handle Guzzle timeouts with async promises

Viewed 667

I am sending multiple async promises with a guzzle timeout set to 30, I am wondering how to capture if any promises timed out so that I can report on this error. Please see the code below. Essentially I want to use any responses I can before timeout and capture those that do timeout.

foreach ($apiRequests as $guzzleParameters) {
    $request = new Request($guzzleParameters->getType(), $guzzleParameters->getApiEndpoint(), $guzzleParameters->getHeaders(), $guzzleParameters->getBody());
    $promises[$guzzleParameters->createKey()] = $this->client->sendAsync($request)->then(
                function (ResponseInterface $res) {
                    return $res;
                },
                function (RequestException $e) {
                    switch ($e->getCode()) {
                        case 400:
                        // log error 
                            break;
                        case 401:
                        // log error 
                            break;
                        case 403:
                        // log error 
                            break;
                        case 404:
                        // log error 
                            break;
                    }
                    return $e->getResponse();
                }
            );
        }
$responses = Promise\Utils::settle($promises)->wait(true);
1 Answers

As I have understood you want to record time of each request in async and then you can add it up and put a flag that when summation reaches more than 30.

NOTE: Non tested code but the on_stats portion code is tested

foreach ($apiRequests as $key => $guzzleParameters) {
    $LogStats = [];
    $request = new Request($guzzleParameters->getType(), $guzzleParameters->getApiEndpoint(), $guzzleParameters->getHeaders(), $guzzleParameters->getBody());
    $promises[$guzzleParameters->createKey()] = $this->client->sendAsync($request, [
                    'on_stats' => function (\GuzzleHttp\TransferStats $stats) {
                        // $LogStats["uri"] = $stats->getEffectiveUri();
                        $LogStats[$key]["time"] = $stats->getTransferTime();
                        // $LogStats["stats"] = json_encode($stats->getHandlerStats());
                        // Log::debug("\n--------------------------------\nDebug Solr Request Stats :: ", $LogStats);
                    }
                ])->then(
                function (ResponseInterface $res) {
                    return $res;
                },
                function (RequestException $e) {
                     // ....
                    }
                    return $e->getResponse();
                }
            );
        }
$responses = Promise\Utils::settle($promises)->wait(true);

Here I have used on_stats, you can put a count on all the time and then sum it up and once it reaches 30 set flag as true. then you can know after which key the request failed.

Related