72 lines
2.1 KiB
JavaScript
72 lines
2.1 KiB
JavaScript
/**
|
|
* @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 };
|