Skip to content

Move instance loading into Effect service#25277

Open
kitlangton wants to merge 8 commits intodevfrom
kit/instance-loader-service
Open

Move instance loading into Effect service#25277
kitlangton wants to merge 8 commits intodevfrom
kit/instance-loader-service

Conversation

@kitlangton
Copy link
Copy Markdown
Contributor

Summary

  • Add an Effect-backed InstanceStore for instance load, cache, reload, and disposal.
  • Use InstanceStore in HttpApi instance context middleware so routed requests receive InstanceRef and WorkspaceRef without entering legacy ALS.
  • Add focused tests for InstanceStore behavior and update HttpApi instance-context test wiring.

Tests

  • bun run test:ci test/project/instance.test.ts
  • bun run test:ci test/server/httpapi-instance-context.test.ts
  • bun run test:ci test/effect/instance-state.test.ts
  • git diff --check

Notes

  • bun typecheck was blocked locally after using dependency symlinks from the main checkout by an unrelated @opencode-ai/plugin export mismatch (WorkspaceAdapter vs WorkspaceAdaptor).

: await project
.runPromise((svc) => svc.fromDirectory(input.directory))
.then(({ project, sandbox }) => ({
export interface Store {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should probably be called interface right?


const reload = Effect.fn("InstanceStore.reload")(function* (input: LoadInput) {
const directory = AppFileSystem.resolve(input.directory)
Log.Default.info("reloading instance", { directory })
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hello

workspace: WorkspaceContext.workspaceID,
payload: {
type: "server.instance.disposed",
properties: {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hi

}),
)

const disposeContext = Effect.fn("InstanceStore.disposeContext")(function* (ctx: InstanceContext) {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test

@kitlangton kitlangton force-pushed the kit/instance-loader-service branch from e4aedda to 8a63cbe Compare May 1, 2026 21:15
export class Service extends Context.Service<Service, Interface>()("@opencode/InstanceStore") {}

interface Entry {
readonly deferred: Deferred.Deferred<InstanceContext>
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a test

kitlangton added 3 commits May 1, 2026 22:02
The manual Deferred slot + uninterruptibleMask + identity check
collapses into Effect.cachedWithTTL(_, Duration.zero): concurrent
callers share the in-flight execution, and the cache expires on
completion so the next call runs fresh. Adds a test pinning the
re-arm semantic.
Previously reload always called disposeInstance + emitted server.instance.disposed
even when no previous entry existed in the cache, sending a phantom dispose
event for an instance that was never loaded.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant