Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 24 additions & 4 deletions apps/server/src/provider/Layers/OpenCodeProvider.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const runtimeMock = {
runVersionError: null as Error | null,
versionStdout: DEFAULT_VERSION_STDOUT,
inventoryError: null as Error | null,
closeCalls: 0,
inventory: {
providerList: { connected: [] as string[], all: [] as unknown[], default: {} },
agents: [] as unknown[],
Expand All @@ -32,6 +33,7 @@ const runtimeMock = {
this.state.runVersionError = null;
this.state.versionStdout = DEFAULT_VERSION_STDOUT;
this.state.inventoryError = null;
this.state.closeCalls = 0;
this.state.inventory = {
providerList: { connected: [], all: [] as unknown[], default: {} },
agents: [] as unknown[],
Expand All @@ -46,10 +48,19 @@ const OpenCodeRuntimeTestDouble: OpenCodeRuntimeShape = {
exitCode: Effect.never,
}),
connectToOpenCodeServer: ({ serverUrl }) =>
Effect.succeed({
url: serverUrl ?? "http://127.0.0.1:4301",
exitCode: null,
external: Boolean(serverUrl),
Effect.gen(function* () {
if (!serverUrl) {
yield* Effect.addFinalizer(() =>
Effect.sync(() => {
runtimeMock.state.closeCalls += 1;
}),
);
}
return {
url: serverUrl ?? "http://127.0.0.1:4301",
exitCode: null,
external: Boolean(serverUrl),
};
}),
runOpenCodeCommand: () =>
runtimeMock.state.runVersionError
Expand Down Expand Up @@ -188,6 +199,15 @@ it.layer(makeTestLayer())("OpenCodeProviderLive", (it) => {
assert.equal(agentDescriptor.options.find((option) => option.isDefault)?.id, "build");
}),
);

it.effect("closes the local OpenCode server scope after provider refresh", () =>
Effect.gen(function* () {
const provider = yield* OpenCodeProvider;
yield* provider.refresh;

assert.equal(runtimeMock.state.closeCalls, 1);
}),
);
});

it.layer(
Expand Down
20 changes: 20 additions & 0 deletions apps/server/src/provider/opencodeRuntime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,7 @@ const makeOpenCodeRuntime = Effect.gen(function* () {
const child = yield* spawner
.spawn(
ChildProcess.make(input.binaryPath, args, {
detached: process.platform !== "win32",
env: {
...process.env,
OPENCODE_CONFIG_CONTENT: JSON.stringify({}),
Expand All @@ -348,6 +349,25 @@ const makeOpenCodeRuntime = Effect.gen(function* () {
),
);

const killOpenCodeProcessGroup = (signal: NodeJS.Signals) =>
process.platform === "win32"
? child.kill({ killSignal: signal, forceKillAfter: "1 second" }).pipe(Effect.asVoid)
: Effect.sync(() => {
try {
process.kill(-Number(child.pid), signal);
} catch {
// The direct child may already have exited after starting the
// server; the process group kill is best-effort cleanup for
// any serve process left in that group.
}
});
const terminateChild = killOpenCodeProcessGroup("SIGTERM").pipe(
Effect.andThen(Effect.sleep("1 second")),
Effect.andThen(killOpenCodeProcessGroup("SIGKILL")),
Effect.ignore,
);
yield* Scope.addFinalizer(runtimeScope, terminateChild);
Comment thread
cursor[bot] marked this conversation as resolved.

const stdoutRef = yield* Ref.make("");
const stderrRef = yield* Ref.make("");
const readyDeferred = yield* Deferred.make<string, OpenCodeRuntimeError>();
Expand Down
Loading