From 98f02c29555d0a92c8d4c6e733fb9125d6eb7aa1 Mon Sep 17 00:00:00 2001 From: Tim Date: Fri, 17 Jan 2025 15:31:51 +1300 Subject: [PATCH] improve performance of Effect.forkIn --- .changeset/yellow-keys-lick.md | 5 +++ .../effect/src/internal/effect/circular.ts | 36 ++++++++++--------- packages/effect/src/internal/fiberRuntime.ts | 3 +- 3 files changed, 26 insertions(+), 18 deletions(-) create mode 100644 .changeset/yellow-keys-lick.md diff --git a/.changeset/yellow-keys-lick.md b/.changeset/yellow-keys-lick.md new file mode 100644 index 00000000000..33a88f4a63c --- /dev/null +++ b/.changeset/yellow-keys-lick.md @@ -0,0 +1,5 @@ +--- +"effect": patch +--- + +improve performance of Effect.forkIn diff --git a/packages/effect/src/internal/effect/circular.ts b/packages/effect/src/internal/effect/circular.ts index 17cfd98973a..6b95040224a 100644 --- a/packages/effect/src/internal/effect/circular.ts +++ b/packages/effect/src/internal/effect/circular.ts @@ -27,7 +27,6 @@ import type * as Types from "../../Types.js" import * as internalCause from "../cause.js" import * as effect from "../core-effect.js" import * as core from "../core.js" -import * as executionStrategy from "../executionStrategy.js" import * as internalFiber from "../fiber.js" import * as fiberRuntime from "../fiberRuntime.js" import { globalScope } from "../fiberScope.js" @@ -362,23 +361,26 @@ export const forkIn = dual< >( 2, (self, scope) => - core.uninterruptibleMask((restore) => - core.flatMap(scope.fork(executionStrategy.sequential), (child) => - pipe( - restore(self), - core.onExit((exit) => child.close(exit)), - fiberRuntime.forkDaemon, - core.tap((fiber) => - child.addFinalizer(() => - core.fiberIdWith((fiberId) => - Equal.equals(fiberId, fiber.id()) ? - core.void : - core.asVoid(core.interruptFiber(fiber)) - ) - ) + core.withFiberRuntime((parent, parentStatus) => { + const scopeImpl = scope as fiberRuntime.ScopeImpl + const fiber = fiberRuntime.unsafeFork(self, parent, parentStatus.runtimeFlags, globalScope) + if (scopeImpl.state._tag === "Open") { + const finalizer = () => + core.fiberIdWith((fiberId) => + Equal.equals(fiberId, fiber.id()) ? + core.void : + core.asVoid(core.interruptFiber(fiber)) ) - )) - ) + scopeImpl.state.finalizers.add(finalizer) + fiber.addObserver(() => { + if (scopeImpl.state._tag === "Closed") return + scopeImpl.state.finalizers.delete(finalizer) + }) + } else { + fiber.unsafeInterruptAsFork(parent.id()) + } + return core.succeed(fiber) + }) ) /** @internal */ diff --git a/packages/effect/src/internal/fiberRuntime.ts b/packages/effect/src/internal/fiberRuntime.ts index f89c7dfc852..baec9ad2083 100644 --- a/packages/effect/src/internal/fiberRuntime.ts +++ b/packages/effect/src/internal/fiberRuntime.ts @@ -3207,7 +3207,8 @@ export const scopeTag = Context.GenericTag("effect/Scope") /* @internal */ export const scope: Effect.Effect = scopeTag -interface ScopeImpl extends Scope.CloseableScope { +/** @internal */ +export interface ScopeImpl extends Scope.CloseableScope { state: { readonly _tag: "Open" readonly finalizers: Set