fix(RcMap): preserve replacement entries during invalidated resource cleanup - #7516
Conversation
🦋 Changeset detectedLatest commit: 76ecd2d The changes in this PR will be included in the next version bump. This PR includes changesets to release 30 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Bundle Size AnalysisGenerated from PR build output; treat the content below as untrusted.
|
|
|
||
| const o = MutableHashMap.get(self.state.map, key) | ||
| if (o._tag === "None" || o.value !== entry) { | ||
| return Scope.close(entry.scope, Exit.void) |
There was a problem hiding this comment.
Would this leak any running fibers?
There was a problem hiding this comment.
Yes. A detached entry with an already-running finite-TTL timer could leave that fiber asleep until its old deadline after the resource scope was closed. Commit 76ecd2d routes external entry shutdown through closeEntry, which interrupts the idle fiber before closing the scope; the timer-expiry path still terminates naturally from inside that fiber. I also extended the stale-timer regression to assert immediate interruption. The assertion fails on the prior PR head and passes with this commit.
Why
Invalidating a borrowed resource and reacquiring its key lets old cleanup affect the replacement. Zero TTL removes the replacement mapping; infinite TTL leaves the detached old resource unfinalized. An existing finite idle timer can independently remove the replacement.
Closes #7515.
Closes EFF-974.
What Changes
Release and idle expiry check that the key still maps to the entry being cleaned up before removing it.
Scope
A focused RcMap lifecycle fix, with regression coverage for zero, finite, and infinite TTL and a surviving old idle timer. Includes an
effect: patchchangeset covering the consumer-visible RcMap and LayerMap behavior. No public API changes.Verification
All four new regression cases failed before the fix. Fixing release alone passed the three TTL cases but left the stale-timer regression failing; the expiry identity check resolved that remaining failure.
Final result: 25 tests pass, comprising 19 RcMap and 6 LayerMap tests. Type checking, lint, formatting, and changeset validation pass. The standalone reproducer produces the expected results with the fix and no manual resource cleanup.
The full test suite and OpenCode integration were not run.