From e1a0dd68103f1422a25d33473e0723a44c8de0a4 Mon Sep 17 00:00:00 2001 From: Vaayne Date: Thu, 25 Sep 2025 23:30:01 +0800 Subject: [PATCH] feat(timeout): implement extendMessagesTimeout middleware and set server timeouts --- src/main/apiServer/app.ts | 11 +++++++++-- src/main/apiServer/server.ts | 12 ++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/main/apiServer/app.ts b/src/main/apiServer/app.ts index 2bfd722193..fa195549a9 100644 --- a/src/main/apiServer/app.ts +++ b/src/main/apiServer/app.ts @@ -14,6 +14,13 @@ import { modelsRoutes } from './routes/models' const logger = loggerService.withContext('ApiServer') +const LONG_POLL_TIMEOUT_MS = 120 * 60_000 // 120 minutes +const extendMessagesTimeout: express.RequestHandler = (req, res, next) => { + req.setTimeout(LONG_POLL_TIMEOUT_MS) + res.setTimeout(LONG_POLL_TIMEOUT_MS) + next() +} + const app = express() app.use( express.json({ @@ -122,7 +129,7 @@ app.get('/', (_req, res) => { setupOpenAPIDocumentation(app) // Provider-specific messages route requires authentication -app.use('/:provider/v1/messages', authMiddleware, messagesProviderRoutes) +app.use('/:provider/v1/messages', authMiddleware, extendMessagesTimeout, messagesProviderRoutes) // API v1 routes with auth const apiRouter = express.Router() @@ -130,7 +137,7 @@ apiRouter.use(authMiddleware) // Mount routes apiRouter.use('/chat', chatRoutes) apiRouter.use('/mcps', mcpRoutes) -apiRouter.use('/messages', messagesRoutes) +apiRouter.use('/messages', extendMessagesTimeout, messagesRoutes) apiRouter.use('/models', modelsRoutes) apiRouter.use('/agents', agentsRoutes) app.use('/v1', apiRouter) diff --git a/src/main/apiServer/server.ts b/src/main/apiServer/server.ts index 61e8c291de..0cba77aaa3 100644 --- a/src/main/apiServer/server.ts +++ b/src/main/apiServer/server.ts @@ -7,6 +7,10 @@ import { config } from './config' const logger = loggerService.withContext('ApiServer') +const GLOBAL_REQUEST_TIMEOUT_MS = 5 * 60_000 +const GLOBAL_HEADERS_TIMEOUT_MS = GLOBAL_REQUEST_TIMEOUT_MS + 5_000 +const GLOBAL_KEEPALIVE_TIMEOUT_MS = 60_000 + export class ApiServer { private server: ReturnType | null = null @@ -26,6 +30,7 @@ export class ApiServer { // Create server with Express app this.server = createServer(app) + this.applyServerTimeouts(this.server) // Start server return new Promise((resolve, reject) => { @@ -38,6 +43,13 @@ export class ApiServer { }) } + private applyServerTimeouts(server: ReturnType): void { + server.requestTimeout = GLOBAL_REQUEST_TIMEOUT_MS + server.headersTimeout = Math.max(GLOBAL_HEADERS_TIMEOUT_MS, server.requestTimeout + 1_000) + server.keepAliveTimeout = GLOBAL_KEEPALIVE_TIMEOUT_MS + server.setTimeout(0) + } + async stop(): Promise { if (!this.server) return