Skip to content

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

Merged
Sammyjo20 merged 3 commits into
saloonphp:v4from
JonPurvis:fix-shallow-clone-request-stores
Sep 18, 2026
Merged

Sammyjo20 merged 3 commits into
saloonphp:v4from
JonPurvis:fix-shallow-clone-request-stores

Conversation

@JonPurvis

@JonPurvis JonPurvis commented Apr 25, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Fixes #524.

Request uses lazy-initialized object stores (query, headers, config, delay, middlewarePipeline). PHP鈥檚 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
@Sammyjo20
Sammyjo20 merged commit dc27ada into saloonphp:v4 Sep 18, 2026
18 checks passed
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

2 participants