diff --git a/src/backend/index.ts b/src/backend/index.ts index 2a9b302..763d27e 100644 --- a/src/backend/index.ts +++ b/src/backend/index.ts @@ -122,33 +122,57 @@ const server = app.listen(config.port, () => { }); // Graceful shutdown +let isShuttingDown = false; + const gracefulShutdown = async (signal: string): Promise => { + // Prevent multiple shutdown calls + if (isShuttingDown) { + logger.warn(`Shutdown already in progress, ignoring ${signal}`); + return; + } + isShuttingDown = true; + logger.info(`Received ${signal}, shutting down gracefully`); - server.close(async err => { - if (err) { - logger.error('Error closing server', err); - process.exit(1); - } - - try { - await logger.flush(); - process.exit(0); - } catch (error) { - logger.error('Error during graceful shutdown', error as Error); - process.exit(1); - } - }); - - // Force close after 5 seconds - setTimeout(() => { + // Set a hard timeout for Docker (Docker default stop timeout is 10s) + const forceExitTimeout = setTimeout(() => { logger.error('Forced shutdown after timeout'); process.exit(1); - }, 3000); + }, 8000); + + try { + // Stop accepting new connections + await new Promise((resolve, reject) => { + server.close(err => { + if (err) { + logger.error('Error closing server', err); + reject(err); + } else { + logger.info('Server closed successfully'); + resolve(); + } + }); + }); + + // Flush logs + await logger.flush(); + logger.info('Logs flushed successfully'); + + // Clean exit + clearTimeout(forceExitTimeout); + process.exit(0); + } catch (error) { + logger.error('Error during graceful shutdown', error as Error); + clearTimeout(forceExitTimeout); + process.exit(1); + } }; +// Docker sends SIGTERM for graceful shutdown process.on('SIGTERM', () => gracefulShutdown('SIGTERM')); +// Ctrl+C in development process.on('SIGINT', () => gracefulShutdown('SIGINT')); +// Nodemon uses SIGUSR2 for restart process.on('SIGUSR2', () => gracefulShutdown('SIGUSR2')); // nodemon uses SIGUSR2 // Handle server errors diff --git a/src/frontend/src/App.tsx b/src/frontend/src/App.tsx index e0daece..dce6254 100644 --- a/src/frontend/src/App.tsx +++ b/src/frontend/src/App.tsx @@ -78,7 +78,7 @@ const App: React.FC = () => {

Version {versionInfo.version} {versionInfo.createdAt !== 'unknown' && - ` | Released ${new Date(versionInfo.createdAt).toLocaleDateString()}`} + ` | Released ${new Date(versionInfo.createdAt).toLocaleString()}`}

)}