Defer memoized Layer state installation until Effect execution - #6946
Defer memoized Layer state installation until Effect execution#6946fubhy wants to merge 1 commit into
Conversation
|
There was a problem hiding this comment.
Important
This PR currently adds only the regression test; the implementation fix announced in the title is missing. CI will fail until that fix is included.
Reviewed changes
Reviewed packages/effect/test/Layer.test.ts (commit afea745). It adds one regression test under the MemoMap describe block that asserts Layer.buildWithMemoMap does not install a memo-map entry until the returned Effect is executed.
packages/effect/test/Layer.test.ts:455-463— regression test for eager memo-entry installation.
⚠️ Implementation fix is missing
The regression test is well-targeted and confirmed failing locally (expected 1 to equal +0), which matches the PR description. However, the PR title claims the fix is included, while the branch only contains the failing test.
To resolve this before merging, add the deferred-installation implementation in packages/effect/src/Layer.ts so that memoMapBuild constructs the scope, deferred, and memo-map entry inside the returned Effect rather than during Layer build construction.
@v0 or keep the SHA fresh with Dependabot | Fix it ➔ | View workflow run | Using Kimi K2 (free via Pullfrog for OSS) | 𝕏

Summary
Merely constructing a memoized layer build Effect inserts an entry into the memo map. If that Effect is abandoned, a later build can wait forever on its never-completed deferred and the child scope and entry are leaked.
Important
This PR starts with focused failing reproduction tests. Add the implementation fix to this same branch; CI is expected to fail until that fix is included.
Memoized layer construction installs state eagerly
Module:
LayerAudit ID:
core-g-r-layer-memo-entry-installed-eagerlySeverity / confidence: medium / high
What happens
Merely constructing a memoized layer build Effect inserts an entry into the memo map. If that Effect is abandoned, a later build can wait forever on its never-completed deferred and the child scope and entry are leaked.
Why it happens
getOrElseMemoize invokes memoMapBuild immediately. memoMapBuild creates a scope and deferred and inserts the memo entry before returning the Effect that would perform acquisition and install cleanup.
Expected behavior
Layer.buildWithMemoMap returns a lazy Effect; memo entries and acquisition state are established when that Effect executes, not when it is constructed.
Relevant implementation
These links and excerpts are pinned to audit base
c9b56ab507f224426ee8388dc450da447ec4715f.packages/effect/src/Layer.ts:380-418packages/effect/src/Layer.ts:445-455View problematic code at
packages/effect/src/Layer.ts:380-418View exact lines on GitHub
View problematic code at
packages/effect/src/Layer.ts:445-455View exact lines on GitHub
Reproduction
pnpm vitest run packages/effect/test/Layer.test.ts -t "does not memoize a build before its Effect executes"Observed failure: The intended failure was reproduced: the map size was 1 instead of 0; an independent public-API probe also observed a second build timing out.
Implementation handoff
The initial reproduction tests on this branch are the regression specification for the implementation fix that should follow in this PR.
pnpm vitest run packages/effect/test/Layer.test.ts -t "does not memoize a build before its Effect executes"Audit provenance
c9b56ab507f224426ee8388dc450da447ec4715fc9b56ab507f224426ee8388dc450da447ec4715fcore-g-r-layer-memo-entry-installed-eagerly