Add structured logging and ensure CLI shuts down cleanly

This commit is contained in:
Shantur Rathore
2025-11-17 20:21:39 +00:00
parent 08d81f8bb5
commit 719a9c9c74
13 changed files with 255 additions and 55 deletions

View File

@@ -13,6 +13,7 @@ import { registerEventRoutes } from "./routes/events"
import { registerStorageRoutes } from "./routes/storage"
import { ServerMeta } from "../api-types"
import { InstanceStore } from "../storage/instance-store"
import { Logger } from "../logger"
interface HttpServerDeps {
host: string
@@ -24,10 +25,24 @@ interface HttpServerDeps {
eventBus: EventBus
serverMeta: ServerMeta
instanceStore: InstanceStore
logger: Logger
}
export function createHttpServer(deps: HttpServerDeps) {
const app = Fastify({ logger: false })
const fastifyLogger = deps.logger.child({ module: "http" })
const app = Fastify({ logger: fastifyLogger as any })
const sseClients = new Set<() => void>()
const registerSseClient = (cleanup: () => void) => {
sseClients.add(cleanup)
return () => sseClients.delete(cleanup)
}
const closeSseClients = () => {
for (const cleanup of Array.from(sseClients)) {
cleanup()
}
sseClients.clear()
}
app.register(cors, {
origin: true,
@@ -38,12 +53,15 @@ export function createHttpServer(deps: HttpServerDeps) {
registerConfigRoutes(app, { configStore: deps.configStore, binaryRegistry: deps.binaryRegistry })
registerFilesystemRoutes(app, { fileSystemBrowser: deps.fileSystemBrowser })
registerMetaRoutes(app, { serverMeta: deps.serverMeta })
registerEventRoutes(app, { eventBus: deps.eventBus })
registerEventRoutes(app, { eventBus: deps.eventBus, registerClient: registerSseClient })
registerStorageRoutes(app, { instanceStore: deps.instanceStore })
return {
instance: app,
start: () => app.listen({ port: deps.port, host: deps.host }),
stop: () => app.close(),
stop: () => {
closeSseClients()
return app.close()
},
}
}

View File

@@ -4,6 +4,7 @@ import { WorkspaceEventPayload } from "../../api-types"
interface RouteDeps {
eventBus: EventBus
registerClient: (cleanup: () => void) => () => void
}
export function registerEventRoutes(app: FastifyInstance, deps: RouteDeps) {
@@ -26,12 +27,23 @@ export function registerEventRoutes(app: FastifyInstance, deps: RouteDeps) {
reply.raw.write(`:hb ${Date.now()}\n\n`)
}, 15000)
let closed = false
const close = () => {
if (closed) return
closed = true
clearInterval(heartbeat)
unsubscribe()
reply.raw.end?.()
}
request.raw.on("close", close)
request.raw.on("error", close)
const unregister = deps.registerClient(close)
const handleClose = () => {
close()
unregister()
}
request.raw.on("close", handleClose)
request.raw.on("error", handleClose)
})
}