initial commit
This commit is contained in:
71
server/shutdown.js
Normal file
71
server/shutdown.js
Normal file
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
* @cc-platform/server/shutdown — Graceful shutdown handler
|
||||
*
|
||||
* Extracted from both servers' SIGINT/SIGTERM handling.
|
||||
* Inventory-Manager has the more thorough implementation (SIGTERM,
|
||||
* unhandled rejection, uncaught exception); remoteturtle only has SIGINT.
|
||||
* This module provides the comprehensive version for all services.
|
||||
*
|
||||
* Usage:
|
||||
* const { setupGracefulShutdown } = require('@cc-platform/server/shutdown');
|
||||
* setupGracefulShutdown({
|
||||
* cleanup: [
|
||||
* () => wsManager.close(),
|
||||
* () => db.close(),
|
||||
* ],
|
||||
* });
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Set up graceful shutdown handlers for SIGINT, SIGTERM, and optionally
|
||||
* unhandled rejections and uncaught exceptions.
|
||||
*
|
||||
* @param {Object} [opts={}] - Options
|
||||
* @param {Function[]} [opts.cleanup=[]] - Array of cleanup functions (sync or async)
|
||||
* @param {boolean} [opts.catchUnhandled=true] - Whether to handle unhandled rejections/exceptions
|
||||
* @param {string} [opts.serviceName] - Service name for log messages
|
||||
* @returns {{ shutdown: Function }} Object with manual shutdown trigger
|
||||
*/
|
||||
function setupGracefulShutdown(opts = {}) {
|
||||
const cleanupFns = opts.cleanup || [];
|
||||
const serviceName = opts.serviceName || 'platform';
|
||||
let shuttingDown = false;
|
||||
|
||||
async function shutdown(signal) {
|
||||
if (shuttingDown) return;
|
||||
shuttingDown = true;
|
||||
|
||||
console.log(`\n[${serviceName}] ${signal} received, cleaning up...`);
|
||||
|
||||
for (const fn of cleanupFns) {
|
||||
try {
|
||||
await fn();
|
||||
} catch (e) {
|
||||
console.error(`[${serviceName}] Cleanup error:`, e.message);
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`[${serviceName}] Cleanup complete`);
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
process.on('SIGINT', () => shutdown('SIGINT'));
|
||||
process.on('SIGTERM', () => shutdown('SIGTERM'));
|
||||
|
||||
if (opts.catchUnhandled !== false) {
|
||||
process.on('unhandledRejection', (reason) => {
|
||||
console.error(`[${serviceName}] Unhandled rejection:`, reason);
|
||||
});
|
||||
|
||||
process.on('uncaughtException', (err) => {
|
||||
console.error(`[${serviceName}] Uncaught exception:`, err);
|
||||
shutdown('uncaughtException');
|
||||
});
|
||||
}
|
||||
|
||||
return { shutdown };
|
||||
}
|
||||
|
||||
module.exports = { setupGracefulShutdown };
|
||||
Reference in New Issue
Block a user