-
-
Notifications
You must be signed in to change notification settings - Fork 118
Open
Description
Using Pool with PagePaginated requests will send the same page for all concurrent requests, since $request is shallow cloned and $query is an ArrayStore object, it will be the same $query object for all concurrent requests if it was initialized before calling ->paginate()
this causes all requests sent together to have the same $query as well as other object properties
$connector = Connector::make();
$request = Request::make();
$request->query()->add('key', 'value'); // this will initialize the $query ArrayStore
$paginator = $connector->paginate($request); // this will clone $request internally
$actualPages = [];
$pool = $paginator
->setMaxPages(10)
->pool(
concurrency: 5,
responseHandler: function (Response $response) use (&$actualPages) {
$actualPages[] = $response->json('meta.current_page');
});
$promise = $pool->send();
$promise->wait();
$actualPages;
// expected: [1, 2, 3, 5, 6, 4, 7, 8, 9, 10];
// actual: [1, 6, 6, 6, 6, 6, 8, 7, 10, 10];to avoid that we overrode the function applyPagination and changed it to:
protected function applyPagination(Request $request): Request
{
if ($request->query()->get('page') === null) {
(function () {
$currentQuery = $this->query()->all();
unset($this->query);
$this->query()->merge($currentQuery);
})->call($request);
}
return parent::applyPagination($request);
}$query, $headers, $config, and $delay are all objects, if any of them is initialized before cloning they will be shared between all requests, but i think only pagination needs the deep clone for query
abublihi
Metadata
Metadata
Assignees
Labels
No labels