'use strict';
|
|
const cluster = require('cluster');
|
const getExitFunction = require('./exit');
|
|
const init = Symbol('graceful-process-init');
|
|
module.exports = (options = {}) => {
|
const logger = options.logger || console;
|
let logLevel = (options.logLevel || 'info').toLowerCase();
|
if (logger !== console) {
|
// don't handle custom logger level
|
logLevel = 'info';
|
}
|
const printLogLevels = {
|
info: true,
|
warn: true,
|
error: true,
|
};
|
if (logLevel === 'warn') {
|
printLogLevels.info = false;
|
} else if (logLevel === 'error') {
|
printLogLevels.info = false;
|
printLogLevels.warn = false;
|
}
|
const label = options.label || `graceful-process#${process.pid}`;
|
|
if (process[init]) {
|
printLogLevels.warn && logger.warn('[%s] graceful-process init already', label);
|
return;
|
}
|
process[init] = true;
|
|
const exit = getExitFunction(options.beforeExit, logger, label);
|
|
// https://github.com/eggjs/egg-cluster/blob/master/lib/agent_worker.js#L35
|
// exit gracefully
|
process.once('SIGTERM', () => {
|
printLogLevels.info && logger.info('[%s] receive signal SIGTERM, exiting with code:0', label);
|
exit(0);
|
});
|
|
process.once('exit', code => {
|
const level = code === 0 ? 'info' : 'error';
|
printLogLevels[level] && logger[level]('[%s] exit with code:%s', label, code);
|
});
|
|
if (cluster.worker) {
|
// cluster mode
|
// https://github.com/nodejs/node/blob/6caf1b093ab0176b8ded68a53ab1ab72259bb1e0/lib/internal/cluster/child.js#L28
|
cluster.worker.once('disconnect', () => {
|
// ignore suicide disconnect event
|
if (cluster.worker.exitedAfterDisconnect) return;
|
logger.error('[%s] receive disconnect event in cluster fork mode, exitedAfterDisconnect:false', label);
|
});
|
} else {
|
// child_process mode
|
process.once('disconnect', () => {
|
// wait a loop for SIGTERM event happen
|
setImmediate(() => {
|
// if disconnect event emit, maybe master exit in accident
|
logger.error('[%s] receive disconnect event on child_process fork mode, exiting with code:110', label);
|
exit(110);
|
});
|
});
|
}
|
};
|