From fb0ba374acd4f9932fa0d9e6ffe22586e38aa821 Mon Sep 17 00:00:00 2001 From: ZacharyZcR Date: Mon, 18 May 2026 05:29:37 +0800 Subject: [PATCH] fix: flush in-memory database to disk on graceful shutdown SIGTERM/SIGINT handlers previously called process.exit(0) immediately without persisting the in-memory SQLite database. This caused session data loss on container restart, forcing users to re-authenticate. --- src/backend/starter.ts | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/src/backend/starter.ts b/src/backend/starter.ts index e6464b6ec..4569534fd 100644 --- a/src/backend/starter.ts +++ b/src/backend/starter.ts @@ -194,29 +194,32 @@ import { duration: Date.now() - initStartTime, }); - process.on("SIGINT", () => { - systemLogger.info( - "Received SIGINT signal, initiating graceful shutdown...", - { operation: "shutdown" }, - ); + const gracefulShutdown = async (signal: string) => { + systemLogger.info(`Received ${signal}, initiating graceful shutdown...`, { + operation: "shutdown", + }); + try { + const { saveMemoryDatabaseToFile } = await import( + "./database/db/index.js" + ); + await saveMemoryDatabaseToFile(); + systemLogger.info("Database saved to disk before exit", { + operation: "shutdown_db_saved", + }); + } catch (error) { + systemLogger.error("Failed to save database during shutdown", error, { + operation: "shutdown_db_save_failed", + }); + } process.exit(0); - }); + }; - process.on("SIGTERM", () => { - systemLogger.info( - "Received SIGTERM signal, initiating graceful shutdown...", - { operation: "shutdown" }, - ); - process.exit(0); - }); + process.on("SIGINT", () => gracefulShutdown("SIGINT")); + process.on("SIGTERM", () => gracefulShutdown("SIGTERM")); process.on("message", (msg: { type?: string }) => { if (msg?.type === "shutdown") { - systemLogger.info( - "Received IPC shutdown, initiating graceful shutdown...", - { operation: "shutdown" }, - ); - process.exit(0); + gracefulShutdown("IPC shutdown"); } });