UNPKG

@hirosystems/api-toolkit

Version:
82 lines 3.01 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.shutdown = shutdown; exports.registerShutdownConfig = registerShutdownConfig; const time_1 = require("../helpers/time"); const logger_1 = require("../logger"); const SHUTDOWN_SIGNALS = ['SIGINT', 'SIGTERM']; const shutdownConfigs = []; let isShuttingDown = false; /** * Start a graceful API shutdown. */ async function shutdown() { if (isShuttingDown) { return; } isShuttingDown = true; const timeoutMs = parseInt(process.env['STACKS_SHUTDOWN_FORCE_KILL_TIMEOUT'] ?? '60') * 1000; let errorEncountered = false; for (const config of shutdownConfigs) { try { logger_1.logger.info(`Closing ${config.name}...`); const gracefulShutdown = await (0, time_1.resolveOrTimeout)(Promise.resolve(config.handler()), timeoutMs, !config.forceKillable, () => logger_1.logger.error(`${config.name} is taking longer than expected to shutdown, possibly hanging indefinitely`)); if (!gracefulShutdown) { if (config.forceKillable && config.forceKillHandler) { await Promise.resolve(config.forceKillHandler()); } logger_1.logger.error(`${config.name} was force killed after taking longer than ${timeoutMs}ms to shutdown`); } else { logger_1.logger.info(`${config.name} closed`); } } catch (error) { errorEncountered = true; logger_1.logger.error(error, `Error running ${config.name} shutdown handler`); } } if (errorEncountered) { process.exit(1); } else { logger_1.logger.info('App shutdown successful.'); process.exit(); } } let shutdownSignalsRegistered = false; function registerShutdownSignals() { if (shutdownSignalsRegistered) { return; } shutdownSignalsRegistered = true; SHUTDOWN_SIGNALS.forEach(sig => { process.once(sig, () => { logger_1.logger.info(`Shutting down... received signal: ${sig}`); void shutdown(); }); }); process.once('unhandledRejection', error => { logger_1.logger.error(error, 'unhandledRejection'); logger_1.logger.error('Shutting down... received unhandledRejection.'); void shutdown(); }); process.once('uncaughtException', error => { logger_1.logger.error(error, 'uncaughtException'); logger_1.logger.error('Shutting down... received uncaughtException.'); void shutdown(); }); process.once('beforeExit', () => { logger_1.logger.error('Shutting down... received beforeExit.'); void shutdown(); }); } /** * Register shutdown handlers for different API components. * @param configs - Array of shutdown configurations */ function registerShutdownConfig(...configs) { registerShutdownSignals(); shutdownConfigs.push(...configs); } //# sourceMappingURL=index.js.map