import { env } from './config/env.js'; import { db } from './db/client.js'; import { createApp } from './app.js'; import { ChatService } from './services/chat-service.js'; import { clearAllChatConversationJobStates, ensureChatConversationTables } from './services/chat-room-service.js'; import { shutdownNotificationProvider } from './services/notification-service.js'; import { PlanWorker } from './workers/plan-worker.js'; const app = createApp(); const planWorker = new PlanWorker(app.log); const chatService = new ChatService(app.log); const startedAt = Date.now(); let shutdownPromise: Promise | null = null; app.server.on('upgrade', chatService.attachUpgradeHandler()); async function start() { try { await ensureChatConversationTables(); await clearAllChatConversationJobStates(); await app.listen({ host: '0.0.0.0', port: env.PORT, }); planWorker.start(); } catch (error) { app.log.error(error); process.exit(1); } } async function shutdown(signal: string) { if (shutdownPromise) { return shutdownPromise; } shutdownPromise = (async () => { app.log.warn({ signal, pid: process.pid, uptimeSeconds: Math.round((Date.now() - startedAt) / 1000), rssBytes: process.memoryUsage().rss, }, 'Received shutdown signal'); try { await planWorker.stop(); chatService.close(); await app.close(); await shutdownNotificationProvider(); await db.destroy(); process.exitCode = 0; } catch (error) { app.log.error({ error, signal }, 'Failed to shut down cleanly'); process.exitCode = 1; } })(); return shutdownPromise; } process.on('SIGINT', () => { void shutdown('SIGINT'); }); process.on('SIGTERM', () => { void shutdown('SIGTERM'); }); void start();