diff --git a/.changeset/two-tips-knock.md b/.changeset/two-tips-knock.md new file mode 100644 index 00000000000..570462e4ac2 --- /dev/null +++ b/.changeset/two-tips-knock.md @@ -0,0 +1,5 @@ +--- +"effect": patch +--- + +use Map for Scope finalizers, to ensure they are always added diff --git a/packages/effect/src/internal/effect/circular.ts b/packages/effect/src/internal/effect/circular.ts index 6b95040224a..bcd4174d4cb 100644 --- a/packages/effect/src/internal/effect/circular.ts +++ b/packages/effect/src/internal/effect/circular.ts @@ -371,10 +371,11 @@ export const forkIn = dual< core.void : core.asVoid(core.interruptFiber(fiber)) ) - scopeImpl.state.finalizers.add(finalizer) + const key = {} + scopeImpl.state.finalizers.set(key, finalizer) fiber.addObserver(() => { if (scopeImpl.state._tag === "Closed") return - scopeImpl.state.finalizers.delete(finalizer) + scopeImpl.state.finalizers.delete(key) }) } else { fiber.unsafeInterruptAsFork(parent.id()) diff --git a/packages/effect/src/internal/fiberRuntime.ts b/packages/effect/src/internal/fiberRuntime.ts index baec9ad2083..88727d780d2 100644 --- a/packages/effect/src/internal/fiberRuntime.ts +++ b/packages/effect/src/internal/fiberRuntime.ts @@ -3211,7 +3211,7 @@ export const scope: Effect.Effect = scopeTag export interface ScopeImpl extends Scope.CloseableScope { state: { readonly _tag: "Open" - readonly finalizers: Set + readonly finalizers: Map<{}, Scope.Scope.Finalizer> } | { readonly _tag: "Closed" readonly exit: Exit.Exit @@ -3220,7 +3220,7 @@ export interface ScopeImpl extends Scope.CloseableScope { const scopeUnsafeAddFinalizer = (scope: ScopeImpl, fin: Scope.Scope.Finalizer): void => { if (scope.state._tag === "Open") { - scope.state.finalizers.add(fin) + scope.state.finalizers.set({}, fin) } } @@ -3237,12 +3237,13 @@ const ScopeImplProto: Omit = { newScope.state = this.state return newScope } + const key = {} const fin = (exit: Exit.Exit) => newScope.close(exit) - this.state.finalizers.add(fin) + this.state.finalizers.set(key, fin) scopeUnsafeAddFinalizer(newScope, (_) => core.sync(() => { if (this.state._tag === "Open") { - this.state.finalizers.delete(fin) + this.state.finalizers.delete(key) } })) return newScope @@ -3297,7 +3298,7 @@ const ScopeImplProto: Omit = { if (this.state._tag === "Closed") { return fin(this.state.exit) } - this.state.finalizers.add(fin) + this.state.finalizers.set({}, fin) return core.void }) } @@ -3308,7 +3309,7 @@ const scopeUnsafeMake = ( ): ScopeImpl => { const scope = Object.create(ScopeImplProto) scope.strategy = strategy - scope.state = { _tag: "Open", finalizers: new Set() } + scope.state = { _tag: "Open", finalizers: new Map() } return scope }