tui: bypass local SSE event streaming in worker (#19183)
This commit is contained in:
@@ -6,11 +6,14 @@ import { InstanceBootstrap } from "@/project/bootstrap"
|
|||||||
import { Rpc } from "@/util/rpc"
|
import { Rpc } from "@/util/rpc"
|
||||||
import { upgrade } from "@/cli/upgrade"
|
import { upgrade } from "@/cli/upgrade"
|
||||||
import { Config } from "@/config/config"
|
import { Config } from "@/config/config"
|
||||||
|
import { Bus } from "@/bus"
|
||||||
import { GlobalBus } from "@/bus/global"
|
import { GlobalBus } from "@/bus/global"
|
||||||
import { createOpencodeClient, type Event } from "@opencode-ai/sdk/v2"
|
import type { Event } from "@opencode-ai/sdk/v2"
|
||||||
import { Flag } from "@/flag/flag"
|
import { Flag } from "@/flag/flag"
|
||||||
import { setTimeout as sleep } from "node:timers/promises"
|
import { setTimeout as sleep } from "node:timers/promises"
|
||||||
import { writeHeapSnapshot } from "node:v8"
|
import { writeHeapSnapshot } from "node:v8"
|
||||||
|
import { WorkspaceContext } from "@/control-plane/workspace-context"
|
||||||
|
import { WorkspaceID } from "@/control-plane/schema"
|
||||||
|
|
||||||
await Log.init({
|
await Log.init({
|
||||||
print: process.argv.includes("--print-logs"),
|
print: process.argv.includes("--print-logs"),
|
||||||
@@ -50,39 +53,55 @@ const startEventStream = (input: { directory: string; workspaceID?: string }) =>
|
|||||||
eventStream.abort = abort
|
eventStream.abort = abort
|
||||||
const signal = abort.signal
|
const signal = abort.signal
|
||||||
|
|
||||||
const fetchFn = (async (input: RequestInfo | URL, init?: RequestInit) => {
|
const workspaceID = input.workspaceID ? WorkspaceID.make(input.workspaceID) : undefined
|
||||||
const request = new Request(input, init)
|
|
||||||
const auth = getAuthorizationHeader()
|
|
||||||
if (auth) request.headers.set("Authorization", auth)
|
|
||||||
return Server.Default().fetch(request)
|
|
||||||
}) as typeof globalThis.fetch
|
|
||||||
|
|
||||||
const sdk = createOpencodeClient({
|
|
||||||
baseUrl: "http://opencode.internal",
|
|
||||||
directory: input.directory,
|
|
||||||
experimental_workspaceID: input.workspaceID,
|
|
||||||
fetch: fetchFn,
|
|
||||||
signal,
|
|
||||||
})
|
|
||||||
|
|
||||||
;(async () => {
|
;(async () => {
|
||||||
while (!signal.aborted) {
|
while (!signal.aborted) {
|
||||||
const events = await Promise.resolve(
|
const shouldReconnect = await WorkspaceContext.provide({
|
||||||
sdk.event.subscribe(
|
workspaceID,
|
||||||
{},
|
fn: () =>
|
||||||
{
|
Instance.provide({
|
||||||
signal,
|
directory: input.directory,
|
||||||
},
|
init: InstanceBootstrap,
|
||||||
),
|
fn: () =>
|
||||||
).catch(() => undefined)
|
new Promise<boolean>((resolve) => {
|
||||||
|
Rpc.emit("event", {
|
||||||
|
type: "server.connected",
|
||||||
|
properties: {},
|
||||||
|
} satisfies Event)
|
||||||
|
|
||||||
if (!events) {
|
let settled = false
|
||||||
await sleep(250)
|
const settle = (value: boolean) => {
|
||||||
continue
|
if (settled) return
|
||||||
}
|
settled = true
|
||||||
|
signal.removeEventListener("abort", onAbort)
|
||||||
|
unsub()
|
||||||
|
resolve(value)
|
||||||
|
}
|
||||||
|
|
||||||
for await (const event of events.stream) {
|
const unsub = Bus.subscribeAll((event) => {
|
||||||
Rpc.emit("event", event as Event)
|
Rpc.emit("event", event as Event)
|
||||||
|
if (event.type === Bus.InstanceDisposed.type) {
|
||||||
|
settle(true)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const onAbort = () => {
|
||||||
|
settle(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
signal.addEventListener("abort", onAbort, { once: true })
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
}).catch((error) => {
|
||||||
|
Log.Default.error("event stream subscribe error", {
|
||||||
|
error: error instanceof Error ? error.message : error,
|
||||||
|
})
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!shouldReconnect || signal.aborted) {
|
||||||
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!signal.aborted) {
|
if (!signal.aborted) {
|
||||||
|
|||||||
Reference in New Issue
Block a user