Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[12.x] Fix Concurrency::run to preserve callback result order #55161

Merged
merged 3 commits into from
Mar 27, 2025

Conversation

chaker2710
Copy link
Contributor

Problem

The current implementation of Concurrency::run() with fork driver does not preserve the original order of callbacks when returning results. This leads to incorrect variable assignment when destructuring the return value, as shown in the documentation example:

[$userCount, $orderCount] = Concurrency::run([
    fn () => DB::table('users')->count(),
    fn () => DB::table('orders')->count(),
]);

If the second callback completes before the first, the results array may be returned in a different order, causing $userCount and $orderCount to be swapped.

Solution

This PR modifies the ForkDriver::run method to associate results with their original keys and return them in the original order after all tasks are completed.

Verified

This commit was signed with the committer’s verified signature.
vszakats Viktor Szakats
…backs

Verified

This commit was signed with the committer’s verified signature.
vszakats Viktor Szakats

Verified

This commit was signed with the committer’s verified signature.
vszakats Viktor Szakats
@taylorotwell
Copy link
Member

Does this work with associative arrays?

@chaker2710
Copy link
Contributor Author

Yes, it works.

The destructuring (list unpacking) syntax like:

[$userCount, $orderCount] = Concurrency::run([
    fn () => DB::table('users')->count(),
    fn () => DB::table('orders')->count(),
]);

can only be used with indexed (numerical) arrays.

If we use associative arrays, the syntax must be:

['users' => $userCount, 'orders' => $orderCount] = Concurrency::run([
    'users' => fn () => DB::table('users')->count(),
    'orders' => fn () => DB::table('orders')->count(),
]);

Just wrote a test for this (not committed yet).
If we’re okay with adding spatie/fork as a dev dependency, I’ll push it.

@taylorotwell taylorotwell merged commit d4776ff into laravel:12.x Mar 27, 2025
39 checks passed
@chaker2710 chaker2710 deleted the fix/concurrency-run-key-order branch April 2, 2025 14:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants