Browse Source

refactor(instance): remove state helper (#22381)

Kit Langton 1 tuần trước cách đây
mục cha
commit
f954854232

+ 2 - 6
packages/opencode/src/project/instance.ts

@@ -6,7 +6,6 @@ import { Log } from "@/util/log"
 import { LocalContext } from "../util/local-context"
 import { Project } from "./project"
 import { WorkspaceContext } from "@/control-plane/workspace-context"
-import { State } from "./state"
 
 export interface InstanceContext {
   directory: string
@@ -113,13 +112,10 @@ export const Instance = {
   restore<R>(ctx: InstanceContext, fn: () => R): R {
     return context.provide(ctx, fn)
   },
-  state<S>(init: () => S, dispose?: (state: Awaited<S>) => Promise<void>): () => S {
-    return State.create(() => Instance.directory, init, dispose)
-  },
   async reload(input: { directory: string; init?: () => Promise<any>; project?: Project.Info; worktree?: string }) {
     const directory = Filesystem.resolve(input.directory)
     Log.Default.info("reloading instance", { directory })
-    await Promise.all([State.dispose(directory), disposeInstance(directory)])
+    await disposeInstance(directory)
     cache.delete(directory)
     const next = track(directory, boot({ ...input, directory }))
 
@@ -141,7 +137,7 @@ export const Instance = {
     const directory = Instance.directory
     const project = Instance.project
     Log.Default.info("disposing instance", { directory })
-    await Promise.all([State.dispose(directory), disposeInstance(directory)])
+    await disposeInstance(directory)
     cache.delete(directory)
 
     GlobalBus.emit("event", {

+ 0 - 70
packages/opencode/src/project/state.ts

@@ -1,70 +0,0 @@
-import { Log } from "@/util/log"
-
-export namespace State {
-  interface Entry {
-    state: any
-    dispose?: (state: any) => Promise<void>
-  }
-
-  const log = Log.create({ service: "state" })
-  const recordsByKey = new Map<string, Map<any, Entry>>()
-
-  export function create<S>(root: () => string, init: () => S, dispose?: (state: Awaited<S>) => Promise<void>) {
-    return () => {
-      const key = root()
-      let entries = recordsByKey.get(key)
-      if (!entries) {
-        entries = new Map<string, Entry>()
-        recordsByKey.set(key, entries)
-      }
-      const exists = entries.get(init)
-      if (exists) return exists.state as S
-      const state = init()
-      entries.set(init, {
-        state,
-        dispose,
-      })
-      return state
-    }
-  }
-
-  export async function dispose(key: string) {
-    const entries = recordsByKey.get(key)
-    if (!entries) return
-
-    log.info("waiting for state disposal to complete", { key })
-
-    let disposalFinished = false
-
-    setTimeout(() => {
-      if (!disposalFinished) {
-        log.warn(
-          "state disposal is taking an unusually long time - if it does not complete in a reasonable time, please report this as a bug",
-          { key },
-        )
-      }
-    }, 10000).unref()
-
-    const tasks: Promise<void>[] = []
-    for (const [init, entry] of entries) {
-      if (!entry.dispose) continue
-
-      const label = typeof init === "function" ? init.name : String(init)
-
-      const task = Promise.resolve(entry.state)
-        .then((state) => entry.dispose!(state))
-        .catch((error) => {
-          log.error("Error while disposing state:", { error, key, init: label })
-        })
-
-      tasks.push(task)
-    }
-    await Promise.all(tasks)
-
-    entries.clear()
-    recordsByKey.delete(key)
-
-    disposalFinished = true
-    log.info("state disposal completed", { key })
-  }
-}

+ 0 - 115
packages/opencode/test/project/state.test.ts

@@ -1,115 +0,0 @@
-import { afterEach, expect, test } from "bun:test"
-
-import { Instance } from "../../src/project/instance"
-import { tmpdir } from "../fixture/fixture"
-
-afterEach(async () => {
-  await Instance.disposeAll()
-})
-
-test("Instance.state caches values for the same instance", async () => {
-  await using tmp = await tmpdir()
-  let n = 0
-  const state = Instance.state(() => ({ n: ++n }))
-
-  await Instance.provide({
-    directory: tmp.path,
-    fn: async () => {
-      const a = state()
-      const b = state()
-      expect(a).toBe(b)
-      expect(n).toBe(1)
-    },
-  })
-})
-
-test("Instance.state isolates values by directory", async () => {
-  await using a = await tmpdir()
-  await using b = await tmpdir()
-  let n = 0
-  const state = Instance.state(() => ({ n: ++n }))
-
-  const x = await Instance.provide({
-    directory: a.path,
-    fn: async () => state(),
-  })
-  const y = await Instance.provide({
-    directory: b.path,
-    fn: async () => state(),
-  })
-  const z = await Instance.provide({
-    directory: a.path,
-    fn: async () => state(),
-  })
-
-  expect(x).toBe(z)
-  expect(x).not.toBe(y)
-  expect(n).toBe(2)
-})
-
-test("Instance.state is disposed on instance reload", async () => {
-  await using tmp = await tmpdir()
-  const seen: string[] = []
-  let n = 0
-  const state = Instance.state(
-    () => ({ n: ++n }),
-    async (value) => {
-      seen.push(String(value.n))
-    },
-  )
-
-  const a = await Instance.provide({
-    directory: tmp.path,
-    fn: async () => state(),
-  })
-  await Instance.reload({ directory: tmp.path })
-  const b = await Instance.provide({
-    directory: tmp.path,
-    fn: async () => state(),
-  })
-
-  expect(a).not.toBe(b)
-  expect(seen).toEqual(["1"])
-})
-
-test("Instance.state is disposed on disposeAll", async () => {
-  await using a = await tmpdir()
-  await using b = await tmpdir()
-  const seen: string[] = []
-  const state = Instance.state(
-    () => ({ dir: Instance.directory }),
-    async (value) => {
-      seen.push(value.dir)
-    },
-  )
-
-  await Instance.provide({
-    directory: a.path,
-    fn: async () => state(),
-  })
-  await Instance.provide({
-    directory: b.path,
-    fn: async () => state(),
-  })
-  await Instance.disposeAll()
-
-  expect(seen.sort()).toEqual([a.path, b.path].sort())
-})
-
-test("Instance.state dedupes concurrent promise initialization", async () => {
-  await using tmp = await tmpdir()
-  let n = 0
-  const state = Instance.state(async () => {
-    n += 1
-    await Bun.sleep(10)
-    return { n }
-  })
-
-  const [a, b] = await Instance.provide({
-    directory: tmp.path,
-    fn: async () => Promise.all([state(), state()]),
-  })
-
-  expect(a).toBe(b)
-  expect(n).toBe(1)
-})