Skip to content

Paginated Pool fails to send the pages correctly #524

@MuathIbnHassan

Description

@MuathIbnHassan

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions