Skip to content

Fix shallow Request clone sharing query/headers/config for pooled sends#549

Open
JonPurvis wants to merge 3 commits intosaloonphp:v4from
JonPurvis:fix-shallow-clone-request-stores
Open

Fix shallow Request clone sharing query/headers/config for pooled sends#549
JonPurvis wants to merge 3 commits intosaloonphp:v4from
JonPurvis:fix-shallow-clone-request-stores

Conversation

@JonPurvis
Copy link
Copy Markdown
Contributor

@JonPurvis JonPurvis commented Apr 25, 2026

Summary

Fixes #524.

Request uses lazy-initialized object stores (query, headers, config, delay, middlewarePipeline). PHP’s default clone is shallow, so if those stores are initialized before cloning, clones share the same instances. Concurrent pools (e.g. async pagination) then mutate the same query bag and requests can send the wrong page (or other params).

Changes

  • Add Request::__clone() to deep-clone any initialized mutable stores.
  • Add MiddlewarePipeline::__clone() to clone internal Pipeline instances so middleware state is not shared across cloned requests.

Before

Runs: 10 | Pages: 10 | Concurrency: 5

Run 1: [1,6,6,6,6,7,6,8,10,10] (unique=5/10)
Run 2: [1,6,6,6,6,6,7,8,10,9] (unique=6/10)
Run 3: [1,6,6,6,6,6,7,8,9,10] (unique=6/10)
Run 4: [1,6,6,6,6,6,7,8,9,10] (unique=6/10)
Run 5: [1,6,6,6,6,7,6,8,9,10] (unique=6/10)
Run 6: [1,6,6,6,6,6,7,8,9,10] (unique=6/10)
Run 7: [1,6,6,6,6,6,7,8,9,10] (unique=6/10)
Run 8: [1,6,6,6,6,6,8,9,8,10] (unique=5/10)
Run 9: [1,6,6,6,6,7,6,8,9,10] (unique=6/10)
Run 10: [1,6,6,6,6,6,7,8,9,10] (unique=6/10)

After

Runs: 10 | Pages: 10 | Concurrency: 5

Run 1: [1,3,4,2,5,7,6,8,9,10] (unique=10/10)
Run 2: [1,2,3,4,6,5,8,7,9,10] (unique=10/10)
Run 3: [1,2,4,3,5,6,7,8,9,10] (unique=10/10)
Run 4: [1,2,3,4,6,5,7,8,10,9] (unique=10/10)
Run 5: [1,3,5,6,7,2,8,9,10,4] (unique=10/10)
Run 6: [1,6,4,2,5,7,3,9,8,10] (unique=10/10)
Run 7: [1,2,4,5,6,7,3,8,9,10] (unique=10/10)
Run 8: [1,2,6,3,5,7,4,8,9,10] (unique=10/10)
Run 9: [1,2,3,4,5,6,7,8,9,10] (unique=10/10)
Run 10: [1,2,4,6,5,3,9,7,10,8] (unique=10/10)

Testing

  • Added regression tests covering:
    • Independent query / headers / config / delay after clone
    • Independent middleware pipelines after clone
    • Concurrent pool() with multiple clones + distinct page query values

@JonPurvis JonPurvis force-pushed the fix-shallow-clone-request-stores branch from d3a7402 to fe0be49 Compare April 25, 2026 17:05
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.

Paginated Pool fails to send the pages correctly

1 participant