feat: add graceful shutdown and PM2 cross-worker messaging

Close all tenant DB pools on SIGTERM/SIGINT for clean restarts.
Support PM2 cluster invalidate-tenant-cache messages.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Consultoria AS
2026-03-15 23:30:08 +00:00
parent b064f15404
commit 96e1ea554c

View File

@@ -1,10 +1,11 @@
import { app } from './app.js'; import { app } from './app.js';
import { env } from './config/env.js'; import { env } from './config/env.js';
import { tenantDb } from './config/database.js';
import { startSatSyncJob } from './jobs/sat-sync.job.js'; import { startSatSyncJob } from './jobs/sat-sync.job.js';
const PORT = parseInt(env.PORT, 10); const PORT = parseInt(env.PORT, 10);
app.listen(PORT, '0.0.0.0', () => { const server = app.listen(PORT, '0.0.0.0', () => {
console.log(`API Server running on http://0.0.0.0:${PORT}`); console.log(`API Server running on http://0.0.0.0:${PORT}`);
console.log(`Environment: ${env.NODE_ENV}`); console.log(`Environment: ${env.NODE_ENV}`);
@@ -13,3 +14,23 @@ app.listen(PORT, '0.0.0.0', () => {
startSatSyncJob(); startSatSyncJob();
} }
}); });
// Graceful shutdown — close all tenant DB pools before exiting
const gracefulShutdown = async (signal: string) => {
console.log(`${signal} received. Shutting down gracefully...`);
server.close(() => {
console.log('HTTP server closed');
});
await tenantDb.shutdown();
process.exit(0);
};
process.on('SIGTERM', () => gracefulShutdown('SIGTERM'));
process.on('SIGINT', () => gracefulShutdown('SIGINT'));
// PM2 cluster: cross-worker cache invalidation
process.on('message', (msg: any) => {
if (msg?.type === 'invalidate-tenant-cache' && msg.tenantId) {
tenantDb.invalidatePool(msg.tenantId);
}
});