如何获取并发 Guzzle Promise 池的运行时间

How to get elapsed time of concurrent Guzzle Promise pool

我使用的是 Guzzle php 版本:6.2.2。是否可以在下面的代码中发送 Promise 已经过的时间 运行?例如。每 5 秒,将经过的时间发送到某个函数?

    $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.

例如:

    $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);
        },
    ]);

您可以在完成的函数中调用函数。每次请求完成时都会调用已完成的函数

在已完成的函数中,您可以调用另一个函数,例如更新数据库中请求的进度。此函数可能是当前对象的成员。所以在你完成的函数中你可以有以下行:

$this->UpdateProgress();

您可以使用 "progress" request option 来实现某些功能。这将为您的池中的每个请求连接到 CURLOPT_PROGRESSFUNCTION 的回调。您可能能够获取触发这些回调的时间,并将其与执行池之前的时间进行比较。

另一种选择是将自定义 TaskQueue 注入 promise library's queue() function 并在那里挂接自定义逻辑。

这可能无法回答您的问题,但对于任何正在寻找如何获取每个 Promise 的经过时间的人来说,您可以简单地这样做:

$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
    },
]);

同样,您可以使用 then 来做到这一点

$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();
    }
);