Skip to content

Commit

Permalink
ensure fiber refs are not inherited by ManagedRuntime (#3845)
Browse files Browse the repository at this point in the history
  • Loading branch information
tim-smart authored Oct 26, 2024
1 parent c244666 commit 59d813a
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 21 deletions.
5 changes: 5 additions & 0 deletions .changeset/twelve-seals-move.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"effect": patch
---

ensure fiber refs are not inherited by ManagedRuntime
15 changes: 9 additions & 6 deletions packages/effect/src/internal/managedRuntime.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { Mutable } from "effect/Types"
import type * as Effect from "../Effect.js"
import * as Effectable from "../Effectable.js"
import type { Exit } from "../Exit.js"
Expand All @@ -8,7 +9,6 @@ import { pipeArguments } from "../Pipeable.js"
import { hasProperty } from "../Predicate.js"
import type * as Runtime from "../Runtime.js"
import * as Scope from "../Scope.js"
import * as effect from "./core-effect.js"
import * as core from "./core.js"
import * as fiberRuntime from "./fiberRuntime.js"
import * as internalLayer from "./layer.js"
Expand Down Expand Up @@ -56,8 +56,9 @@ export const make = <R, ER>(
): M.ManagedRuntime<R, ER> => {
memoMap = memoMap ?? internalLayer.unsafeMakeMemoMap()
const scope = internalRuntime.unsafeRunSyncEffect(fiberRuntime.scopeMake())
const runtimeEffect = internalRuntime.unsafeRunSyncEffect(
effect.memoize(
let buildFiber: Fiber.RuntimeFiber<Runtime.Runtime<R>, ER> | undefined
const runtimeEffect = core.suspend(() => {
buildFiber ??= internalRuntime.unsafeForkEffect(
core.tap(
Scope.extend(
internalLayer.toRuntimeWithMemoMap(layer, memoMap),
Expand All @@ -66,9 +67,11 @@ export const make = <R, ER>(
(rt) => {
self.cachedRuntime = rt
}
)
),
{ scope }
)
)
return core.flatten(buildFiber.await)
})
const self: ManagedRuntimeImpl<R, ER> = Object.assign(Object.create(ManagedRuntimeProto), {
memoMap,
scope,
Expand All @@ -83,7 +86,7 @@ export const make = <R, ER>(
return internalRuntime.unsafeRunPromiseEffect(self.disposeEffect)
},
disposeEffect: core.suspend(() => {
;(self as any).runtime = core.die("ManagedRuntime disposed")
;(self as Mutable<ManagedRuntimeImpl<R, ER>>).runtimeEffect = core.die("ManagedRuntime disposed")
self.cachedRuntime = undefined
return Scope.close(self.scope, core.exitVoid)
}),
Expand Down
38 changes: 23 additions & 15 deletions packages/effect/test/ManagedRuntime.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { ManagedRuntime } from "effect"
import { FiberRefs, List, ManagedRuntime } from "effect"
import * as Context from "effect/Context"
import * as Effect from "effect/Effect"
import * as FiberRef from "effect/FiberRef"
import * as Layer from "effect/Layer"
import * as it from "effect/test/utils/extend"
import { assert, describe, test } from "vitest"
import { assert, describe, it, test } from "effect/test/utils/extend"

describe.concurrent("ManagedRuntime", () => {
test("memoizes the layer build", async () => {
Expand Down Expand Up @@ -50,16 +49,25 @@ describe.concurrent("ManagedRuntime", () => {
assert.strictEqual(count, 1)
})

it.effect(
"is subtype of effect",
() =>
Effect.gen(function*() {
const tag = Context.GenericTag<string>("string")
const layer = Layer.succeed(tag, "test")
const managedRuntime = ManagedRuntime.make(layer)
const runtime = yield* managedRuntime
const result = Context.get(runtime.context, tag)
assert.strictEqual(result, "test")
})
)
it.effect("is subtype of effect", () =>
Effect.gen(function*() {
const tag = Context.GenericTag<string>("string")
const layer = Layer.succeed(tag, "test")
const managedRuntime = ManagedRuntime.make(layer)
const runtime = yield* managedRuntime
const result = Context.get(runtime.context, tag)
assert.strictEqual(result, "test")
}))

it.effect("does not inherit fiber refs", () =>
Effect.gen(function*() {
const tag = Context.GenericTag<string>("string")
const layer = Layer.succeed(tag, "test")
const managedRuntime = ManagedRuntime.make(layer)
const runtime = yield* managedRuntime.runtimeEffect.pipe(
Effect.withLogSpan("test")
)
const result = FiberRefs.getOrDefault(runtime.fiberRefs, FiberRef.currentLogSpan)
assert.deepStrictEqual(result, List.empty())
}))
})

0 comments on commit 59d813a

Please sign in to comment.