Просмотр исходного кода

refactor: tighten instance context helper fallbacks

Kit Langton 2 недель назад
Родитель
Сommit
82da702f64

+ 9 - 6
packages/opencode/src/effect/instance-state.ts

@@ -1,5 +1,6 @@
 import { Effect, Fiber, ScopedCache, Scope, ServiceMap } from "effect"
 import { Instance, type InstanceContext } from "@/project/instance"
+import { Context } from "@/util/context"
 import { InstanceRef } from "./instance-ref"
 import { registerDisposer } from "./instance-registry"
 
@@ -14,7 +15,9 @@ export namespace InstanceState {
   export const bind = <F extends (...args: any[]) => any>(fn: F): F => {
     try {
       return Instance.bind(fn)
-    } catch {}
+    } catch (err) {
+      if (!(err instanceof Context.NotFound)) throw err
+    }
     const fiber = Fiber.getCurrent()
     const ctx = fiber ? ServiceMap.getReferenceUnsafe(fiber.services, InstanceRef) : undefined
     if (!ctx) return fn
@@ -25,10 +28,7 @@ export namespace InstanceState {
     return (yield* InstanceRef) ?? Instance.current
   })()
 
-  export const directory = Effect.fnUntraced(function* () {
-    const ctx = yield* InstanceRef
-    return ctx ? ctx.directory : Instance.directory
-  })()
+  export const directory = Effect.map(context, (ctx) => ctx.directory)
 
   export const make = <A, E = never, R = never>(
     init: (ctx: InstanceContext) => Effect.Effect<A, E, R | Scope.Scope>,
@@ -74,6 +74,9 @@ export namespace InstanceState {
       return yield* ScopedCache.invalidate(self.cache, yield* directory)
     })
 
-  /** Run a sync function with Instance ALS restored from the InstanceRef. */
+  /**
+   * Effect finalizers run on the fiber scheduler after the original async
+   * boundary, so ALS reads like Instance.directory can be gone by then.
+   */
   export const withALS = <T>(fn: () => T) => Effect.map(context, (ctx) => Instance.restore(ctx, fn))
 }

+ 4 - 1
packages/opencode/src/effect/run-service.ts

@@ -1,6 +1,7 @@
 import { Effect, Layer, ManagedRuntime } from "effect"
 import * as ServiceMap from "effect/ServiceMap"
 import { Instance } from "@/project/instance"
+import { Context } from "@/util/context"
 import { InstanceRef } from "./instance-ref"
 
 export const memoMap = Layer.makeMemoMapUnsafe()
@@ -9,7 +10,9 @@ function attach<A, E, R>(effect: Effect.Effect<A, E, R>): Effect.Effect<A, E, R>
   try {
     const ctx = Instance.current
     return Effect.provideService(effect, InstanceRef, ctx)
-  } catch {}
+  } catch (err) {
+    if (!(err instanceof Context.NotFound)) throw err
+  }
   return effect
 }