From 33d282beffcb159f1b08d30f403f2954e6775b4a Mon Sep 17 00:00:00 2001 From: Tim Date: Fri, 17 Jan 2025 16:32:38 +1300 Subject: [PATCH] reduce churn of RcMap idle timeout fiber (#4282) --- packages/effect/src/internal/rcMap.ts | 33 +++++++++------------------ 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/packages/effect/src/internal/rcMap.ts b/packages/effect/src/internal/rcMap.ts index aa93d18712f..131dd771f1a 100644 --- a/packages/effect/src/internal/rcMap.ts +++ b/packages/effect/src/internal/rcMap.ts @@ -1,5 +1,4 @@ import type * as Cause from "../Cause.js" -import type { Clock } from "../Clock.js" import * as Context from "../Context.js" import type * as Deferred from "../Deferred.js" import * as Duration from "../Duration.js" @@ -139,7 +138,6 @@ const getImpl = core.fnUntraced(function*(self: RcMapImpl, key if (o._tag === "Some") { entry = o.value entry.refCount++ - if (entry.fiber) yield* core.interruptFiber(entry.fiber) } else if (Number.isFinite(self.capacity) && MutableHashMap.size(self.state.map) >= self.capacity) { return yield* core.fail( new core.ExceededCapacityException(`RcMap attempted to exceed capacity of ${self.capacity}`) @@ -197,17 +195,18 @@ const release = (self: RcMapImpl, key: K, entry: State.Entry { - if (self.state._tag === "Open" && entry.refCount === 0) { - MutableHashMap.remove(self.state.map, key) - return core.scopeClose(entry.scope, core.exitVoid) - } - return core.void - })), + return core.interruptibleMask(function loop(restore): Effect { + const now = clock.unsafeCurrentTimeMillis() + const remaining = entry.expiresAt - now + if (remaining <= 0) { + if (self.state._tag === "Closed" || entry.refCount > 0) return core.void + MutableHashMap.remove(self.state.map, key) + return restore(core.scopeClose(entry.scope, core.exitVoid)) + } + return core.flatMap(clock.sleep(Duration.millis(remaining)), () => loop(restore)) + }).pipe( fiberRuntime.ensuring(core.sync(() => { entry.fiber = undefined })), @@ -219,16 +218,6 @@ const release = (self: RcMapImpl, key: K, entry: State.Entry(entry: State.Entry, clock: Clock) => - core.suspend(function loop(): Effect { - const now = clock.unsafeCurrentTimeMillis() - const remaining = entry.expiresAt - now - if (remaining <= 0) { - return core.void - } - return core.flatMap(clock.sleep(Duration.millis(remaining)), loop) - }) - /** @internal */ export const keys = (self: RcMap.RcMap): Effect> => { const impl = self as RcMapImpl