Skip to content

Clone singletons per-request for Octane safety (#870)#879

Open
Remo wants to merge 1 commit into
flat3:5.xfrom
ortic:fix/issue-870-octane-singleton-leak
Open

Clone singletons per-request for Octane safety (#870)#879
Remo wants to merge 1 commit into
flat3:5.xfrom
ortic:fix/issue-870-octane-singleton-leak

Conversation

@Remo

@Remo Remo commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

The Lodata model is a container singleton, so under Laravel Octane it and every resource it holds stay resident in memory and are reused across requests. Entity sets and operations were already cloned before any request-scoped state was attached to them, but Singleton::pipe() returned the shared instance directly. During the request cycle Entity::get() and emitJson() then mutated that shared object (setting metadata, advancing the propertyValues iterator, and appending null/generated/computed/navigation property values), leaking and accumulating state across requests.

Clone the singleton in Singleton::pipe(), and give ComplexValue a __clone() that deep-clones the property value collection and resets the metadata so the existing per-request mutations land on the clone rather than the shared model instance.

Adds a regression test that reuses the singleton model across multiple simulated requests and asserts the shared instance is left untouched.

The Lodata model is a container singleton, so under Laravel Octane it and
every resource it holds stay resident in memory and are reused across
requests. Entity sets and operations were already cloned before any
request-scoped state was attached to them, but Singleton::pipe() returned
the shared instance directly. During the request cycle Entity::get() and
emitJson() then mutated that shared object (setting metadata, advancing the
propertyValues iterator, and appending null/generated/computed/navigation
property values), leaking and accumulating state across requests.

Clone the singleton in Singleton::pipe(), and give ComplexValue a __clone()
that deep-clones the property value collection and resets the metadata so
the existing per-request mutations land on the clone rather than the shared
model instance.

Adds a regression test that reuses the singleton model across multiple
simulated requests and asserts the shared instance is left untouched.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant