Zelf
Zelf

Reputation: 2250

How to get elapsed time of concurrent Guzzle Promise pool

I'm using Guzzle php version: 6.2.2. Is it possible in the code below to send the elapsed time the Promise has been running? E.g. every 5 seconds, send the elapsed time to some function?

    $client = new Client([
        'base_uri' => BASE_URL . 'sync/import', // Base URI is used with relative requests
        'timeout'  => 0, // 0 no timeout for operations and watching Promises
        'verify' => true
    ]);

    $requests = function ($syncRequests) {
        foreach ($syncRequests as $key => $headers) {
            yield new Request('PUT', '', ['Content-type' => 'application/json'], json_encode(['json' => ['sync' => $headers]]));
        }
    };

    $pool = new Pool($client, $requests($this->syncRequests), [
        'concurrency' => 10,
        'fulfilled' => function ($response, $index) {
            $this->promiseFulfilled($response, $index);
        },
        'rejected' => function ($reason, $index) {
            $this->promiseRejected($reason, $index);
        },
    ]);

    $promise = $pool->promise(); // Initiate the transfers and create a promise
    $promise->wait(); // Force the pool of requests to complete.

For example:

    $pool = new Pool($client, $requests($this->syncRequests), [
        'concurrency' => 10,
        'while' => function () { // CALLED WHILE THE CONCURRENT REQUESTS ARE RUNNING!!
            $this->elapsedTime();
        },
        'fulfilled' => function ($response, $index) {
            $this->promiseFulfilled($response, $index);
        },
        'rejected' => function ($reason, $index) {
            $this->promiseRejected($reason, $index);
        },
    ]);

Upvotes: 0

Views: 1567

Answers (3)

Bernard Wiesner
Bernard Wiesner

Reputation: 1425

This may not answer your question but to anyone who is searching how to obtain the elapsed time of every Promise you can simply do this:

$startTime = microtime(true);
$pool = new Pool($client, $requests(100), [
    'concurrency' => 5,
    'fulfilled' => function (Response $response, $index) {
        $endTime = microtime(true);
        $executionTime = round($endTime - $this->startTime, 2);
        // dd($executionTim); or log it
    },
    'rejected' => function (RequestException $reason, $index) {
        // this is delivered each failed request
    },
]);

Similarly you can use then to do this

$promise = $client->requestAsync('GET', 'http://httpbin.org/get');
$startTime = microtime(true);
$promise->then(
    function (ResponseInterface $res) {
        $endTime = microtime(true);
        $executionTime = round($endTime - $this->startTime, 2);
        // dd($executionTim); or log it
    },
    function (RequestException $e) {
        echo $e->getMessage() . "\n";
        echo $e->getRequest()->getMethod();
    }
);

Upvotes: 0

Jeremy Lindblom
Jeremy Lindblom

Reputation: 6527

It's possible you could make something work with the "progress" request option. This will hook up a callback to CURLOPT_PROGRESSFUNCTION for every request in your pool. You might be able to get the time when these callbacks are triggered and compare it to the time before you executed the pool.

Another option could be to inject a custom TaskQueue into the promise library's queue() function and hook in custom logic there.

Upvotes: 2

Nadir Latif
Nadir Latif

Reputation: 3773

You can call a function inside the fulfilled function. The fulfilled function is called each time a request completes

Inside the fulfilled function you can call another function that for example updates the progress of the request in database. This function may be a member of the current object. So inside your fulfilled function you can have the following line:

$this->UpdateProgress();

Upvotes: 0

Related Questions