|
@@ -11,8 +11,20 @@ const logger = pino({
|
|
|
const app = createApp(logger)
|
|
const app = createApp(logger)
|
|
|
const server = await buildServer(app, { logger })
|
|
const server = await buildServer(app, { logger })
|
|
|
|
|
|
|
|
|
|
+let stopping = false
|
|
|
const shutdown = async (signal: string) => {
|
|
const shutdown = async (signal: string) => {
|
|
|
|
|
+ if (stopping) return
|
|
|
|
|
+ stopping = true
|
|
|
logger.info({ signal }, 'shutting down')
|
|
logger.info({ signal }, 'shutting down')
|
|
|
|
|
+ // 其他长连接(如 MCP 客户端保持的流):5 秒后强制断开;10 秒仍未退出则直接退出
|
|
|
|
|
+ setTimeout(() => {
|
|
|
|
|
+ logger.warn({}, '仍有连接未关闭,强制断开')
|
|
|
|
|
+ server.server.closeAllConnections()
|
|
|
|
|
+ }, 5000).unref()
|
|
|
|
|
+ setTimeout(() => {
|
|
|
|
|
+ logger.warn({}, '关闭超时,直接退出')
|
|
|
|
|
+ process.exit(0)
|
|
|
|
|
+ }, 10_000).unref()
|
|
|
await server.close()
|
|
await server.close()
|
|
|
await app.mcpUpstream.closeAll()
|
|
await app.mcpUpstream.closeAll()
|
|
|
app.db.$client.close()
|
|
app.db.$client.close()
|
|
@@ -20,6 +32,13 @@ const shutdown = async (signal: string) => {
|
|
|
}
|
|
}
|
|
|
process.on('SIGINT', () => void shutdown('SIGINT'))
|
|
process.on('SIGINT', () => void shutdown('SIGINT'))
|
|
|
process.on('SIGTERM', () => void shutdown('SIGTERM'))
|
|
process.on('SIGTERM', () => void shutdown('SIGTERM'))
|
|
|
|
|
+// 诊断:监听器过多的警告记下调用栈(每种只记一次),用于查找是哪里在累积
|
|
|
|
|
+const warned = new Set<string>()
|
|
|
|
|
+process.on('warning', w => {
|
|
|
|
|
+ if (w.name !== 'MaxListenersExceededWarning' || warned.has(w.name)) return
|
|
|
|
|
+ warned.add(w.name)
|
|
|
|
|
+ logger.warn({ stack: w.stack }, w.message)
|
|
|
|
|
+})
|
|
|
|
|
|
|
|
await server.listen({ host: config.host, port: config.port })
|
|
await server.listen({ host: config.host, port: config.port })
|
|
|
logger.info({ dataDir: config.dataDir }, `AgentServer 已启动:http://${config.host}:${config.port}`)
|
|
logger.info({ dataDir: config.dataDir }, `AgentServer 已启动:http://${config.host}:${config.port}`)
|