fix(cli): dev/dev:offline Ctrl-C 退出防重入并支持二次强制退出
This commit is contained in:
@@ -6,12 +6,35 @@ const { startServer } = require('./serve-dist');
|
|||||||
|
|
||||||
const log = createLogger('dev:offline');
|
const log = createLogger('dev:offline');
|
||||||
let serverRef = null;
|
let serverRef = null;
|
||||||
|
let shuttingDown = false;
|
||||||
|
|
||||||
function runNode(scriptPath) {
|
function runNode(scriptPath) {
|
||||||
const result = spawnSync(process.execPath, [scriptPath], { stdio: 'inherit' });
|
const result = spawnSync(process.execPath, [scriptPath], { stdio: 'inherit' });
|
||||||
return result && Number.isFinite(result.status) ? result.status : 1;
|
return result && Number.isFinite(result.status) ? result.status : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function closeServer(server, exitCode) {
|
||||||
|
if (!server) {
|
||||||
|
process.exit(exitCode);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (typeof server.closeIdleConnections === 'function') server.closeIdleConnections();
|
||||||
|
if (typeof server.closeAllConnections === 'function') server.closeAllConnections();
|
||||||
|
} catch {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
const forceTimer = setTimeout(() => process.exit(exitCode), 2000);
|
||||||
|
if (typeof forceTimer.unref === 'function') forceTimer.unref();
|
||||||
|
|
||||||
|
server.close(() => {
|
||||||
|
clearTimeout(forceTimer);
|
||||||
|
process.exit(exitCode);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const elapsedMs = startTimer();
|
const elapsedMs = startTimer();
|
||||||
log.info('开始', { version: process.env.npm_package_version });
|
log.info('开始', { version: process.env.npm_package_version });
|
||||||
@@ -37,13 +60,24 @@ async function main() {
|
|||||||
|
|
||||||
log.ok('就绪', { ms: elapsedMs(), url: `http://localhost:${actualPort}` });
|
log.ok('就绪', { ms: elapsedMs(), url: `http://localhost:${actualPort}` });
|
||||||
|
|
||||||
const shutdown = () => {
|
const shutdown = (signal) => {
|
||||||
log.info('正在关闭...');
|
if (shuttingDown) return;
|
||||||
if (!serverRef) process.exit(0);
|
shuttingDown = true;
|
||||||
serverRef.close(() => process.exit(0));
|
|
||||||
|
// 让 Ctrl-C 的 ^C 与日志分行显示
|
||||||
|
process.stdout.write('\n');
|
||||||
|
|
||||||
|
log.info('正在关闭...', { signal });
|
||||||
|
|
||||||
|
// 再次 SIGINT:直接强制退出
|
||||||
|
process.once('SIGINT', () => process.exit(130));
|
||||||
|
|
||||||
|
const exit = signal === 'SIGINT' ? 130 : 0;
|
||||||
|
closeServer(serverRef, exit);
|
||||||
};
|
};
|
||||||
process.on('SIGINT', shutdown);
|
|
||||||
process.on('SIGTERM', shutdown);
|
process.once('SIGINT', () => shutdown('SIGINT'));
|
||||||
|
process.once('SIGTERM', () => shutdown('SIGTERM'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (require.main === module) {
|
if (require.main === module) {
|
||||||
|
|||||||
@@ -6,12 +6,35 @@ const { startServer } = require('./serve-dist');
|
|||||||
|
|
||||||
const log = createLogger('dev');
|
const log = createLogger('dev');
|
||||||
let serverRef = null;
|
let serverRef = null;
|
||||||
|
let shuttingDown = false;
|
||||||
|
|
||||||
function runNode(scriptPath) {
|
function runNode(scriptPath) {
|
||||||
const result = spawnSync(process.execPath, [scriptPath], { stdio: 'inherit' });
|
const result = spawnSync(process.execPath, [scriptPath], { stdio: 'inherit' });
|
||||||
return result && Number.isFinite(result.status) ? result.status : 1;
|
return result && Number.isFinite(result.status) ? result.status : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function closeServer(server, exitCode) {
|
||||||
|
if (!server) {
|
||||||
|
process.exit(exitCode);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (typeof server.closeIdleConnections === 'function') server.closeIdleConnections();
|
||||||
|
if (typeof server.closeAllConnections === 'function') server.closeAllConnections();
|
||||||
|
} catch {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
const forceTimer = setTimeout(() => process.exit(exitCode), 2000);
|
||||||
|
if (typeof forceTimer.unref === 'function') forceTimer.unref();
|
||||||
|
|
||||||
|
server.close(() => {
|
||||||
|
clearTimeout(forceTimer);
|
||||||
|
process.exit(exitCode);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const elapsedMs = startTimer();
|
const elapsedMs = startTimer();
|
||||||
log.info('开始', { version: process.env.npm_package_version });
|
log.info('开始', { version: process.env.npm_package_version });
|
||||||
@@ -45,13 +68,21 @@ async function main() {
|
|||||||
|
|
||||||
log.ok('就绪', { ms: elapsedMs(), url: `http://localhost:${actualPort}` });
|
log.ok('就绪', { ms: elapsedMs(), url: `http://localhost:${actualPort}` });
|
||||||
|
|
||||||
const shutdown = () => {
|
const shutdown = (signal) => {
|
||||||
log.info('正在关闭...');
|
if (shuttingDown) return;
|
||||||
if (!serverRef) process.exit(0);
|
shuttingDown = true;
|
||||||
serverRef.close(() => process.exit(0));
|
|
||||||
|
process.stdout.write('\n');
|
||||||
|
log.info('正在关闭...', { signal });
|
||||||
|
|
||||||
|
process.once('SIGINT', () => process.exit(130));
|
||||||
|
|
||||||
|
const exit = signal === 'SIGINT' ? 130 : 0;
|
||||||
|
closeServer(serverRef, exit);
|
||||||
};
|
};
|
||||||
process.on('SIGINT', shutdown);
|
|
||||||
process.on('SIGTERM', shutdown);
|
process.once('SIGINT', () => shutdown('SIGINT'));
|
||||||
|
process.once('SIGTERM', () => shutdown('SIGTERM'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (require.main === module) {
|
if (require.main === module) {
|
||||||
|
|||||||
@@ -170,13 +170,33 @@ async function main() {
|
|||||||
|
|
||||||
log.ok('就绪', { url: `http://localhost:${actualPort}` });
|
log.ok('就绪', { url: `http://localhost:${actualPort}` });
|
||||||
|
|
||||||
const shutdown = () => {
|
let shuttingDown = false;
|
||||||
log.info('正在关闭...');
|
const shutdown = (signal) => {
|
||||||
server.close(() => process.exit(0));
|
if (shuttingDown) return;
|
||||||
|
shuttingDown = true;
|
||||||
|
|
||||||
|
process.stdout.write('\n');
|
||||||
|
log.info('正在关闭...', { signal });
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (typeof server.closeIdleConnections === 'function') server.closeIdleConnections();
|
||||||
|
if (typeof server.closeAllConnections === 'function') server.closeAllConnections();
|
||||||
|
} catch {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
const exit = signal === 'SIGINT' ? 130 : 0;
|
||||||
|
const forceTimer = setTimeout(() => process.exit(exit), 2000);
|
||||||
|
if (typeof forceTimer.unref === 'function') forceTimer.unref();
|
||||||
|
|
||||||
|
server.close(() => {
|
||||||
|
clearTimeout(forceTimer);
|
||||||
|
process.exit(exit);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
process.on('SIGINT', shutdown);
|
process.once('SIGINT', () => shutdown('SIGINT'));
|
||||||
process.on('SIGTERM', shutdown);
|
process.once('SIGTERM', () => shutdown('SIGTERM'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (require.main === module) {
|
if (require.main === module) {
|
||||||
|
|||||||
Reference in New Issue
Block a user