guzzle concurrent request, wait for finished batch before sending next

主宰稳场 提交于 2021-02-08 10:17:41

问题


I thought this following code would work this way:

  1. a batch in the number of CONCURRENT_REQUESTS is send
  2. it is waited until all of these requests are finished
  3. the next batch of the above number is send
  4. and so on

but in reality if I comment line 14 [usleep(...)] it seems the request batches are send as fast as possible generating thousands of queries to the server. Is it possible to change it? How do I change this behavior?

<?php
$pool = $this->getPool();
if (false !== $pool) {
    $pool->promise()->wait();
}
private function getPool()
{
  $requests = function ($data) {
    foreach ($data as $index => $datum) {
        yield $this->patch($datum)->then(function (
                $response
            ) use ($index) {
                usleep(SLEEP_TIME_IN_SECONDS *1000000);
                return [
                    'response' => $response,
                    'index'    => $index
                ];
            });
        }
    };
    return new EachPromise($requests($data), [
        'concurrency' => CONCURRENT_REQUESTS,
        'fulfilled'   => function ($response, $index) use ($data) {
            // log
        },
        'rejected'    => function ($reason, $index) use ($data) {
            // do stuff
        }
    ]);
}
private function patch($data)
{
    $request = new Request(REQUEST_TYPE_PATCH, $url, $this->getPatchHeaders());
    return $this->client->sendAsync($request);
}

回答1:


It works for me with the same (by meaning) code.

use GuzzleHttp\Client;
use function GuzzleHttp\Promise\each_limit;

$client = new Client();

$requests = function () use ($client) {
    foreach (range(1, 15) as $index) {
        echo "Starting $index query...\n";

        yield $client->getAsync('http://google.com/')
            ->then(function ($response) use ($index) {
                echo "Request $index completed successfully.\n";

                return [
                    'response' => $response,
                    'index'    => $index
                ];
            });
    }
};

$promise = each_limit(
    $requests(),
    3
    // fulfiled
    // rejected
);

$promise->wait();

And the result is:

Starting 1 query...
Starting 2 query...
Starting 3 query...
Request 3 completed successfully.
Starting 4 query...
Request 2 completed successfully.
Starting 5 query...
Request 4 completed successfully.
Starting 6 query...
Request 1 completed successfully.
Starting 7 query...
Request 5 completed successfully.
Starting 8 query...
Request 6 completed successfully.
Starting 9 query...
Request 7 completed successfully.
Starting 10 query...
Request 8 completed successfully.
Starting 11 query...
Request 9 completed successfully.
Starting 12 query...
Request 10 completed successfully.
Starting 13 query...
Request 11 completed successfully.
Starting 14 query...
Request 12 completed successfully.
Starting 15 query...
Request 13 completed successfully.
Request 14 completed successfully.
Request 15 completed successfully.

So it really works. Please check your code again. Try to update to the latest version of Guzzle (I tried with 6.2.2).



来源:https://stackoverflow.com/questions/40242226/guzzle-concurrent-request-wait-for-finished-batch-before-sending-next

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!