Skip to content

Commit

Permalink
feat: add kill timeout args
Browse files Browse the repository at this point in the history
  • Loading branch information
czy88840616 committed Dec 8, 2024
1 parent 3536b23 commit 6aeb30f
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 19 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ $ npx mwtsc --watch --run ./bootstrap.js
# run with tsc options
$ npx mwtsc --watch --project tsconfig.production.json --run ./bootstrap.js

# run with kill timeout
$ npx mwtsc --watch --run ./bootstrap.js --kill-timeout 5000

# the child process keep avaliable during the development
$ npx mwtsc --watch --run ./bootstrap.js --keepalive

Expand All @@ -28,6 +31,15 @@ $ npx mwtsc --watch --inspect-brk --run ./bootstrap.js
* 2、support copy non-ts file to dist directory when build source code
* 3、support ts alias path by tsc-alias


## About `--kill-timeout`

Process kill timeout in milliseconds. When restarting the application, if the process doesn't exit within this time, it will be forcefully killed.

Default: `2000`

When using `Ctrl+C` to stop the process, it will follow the `kill-timeout` to kill the process.

## About `--inspect` and `--inspect-brk`

If you're using VSCode or JetBrains IntelliJ IDEA (or other IDEs), you won't need to manually start the child process with debugging flags like --inspect or --inspect-brk. The IDE will automatically attach the debugger to the child process.
Expand Down
Empty file modified bin/mwtsc.js
100644 → 100755
Empty file.
69 changes: 51 additions & 18 deletions lib/process.js
Original file line number Diff line number Diff line change
Expand Up @@ -192,29 +192,62 @@ const forkRun = (runCmdPath, runArgs = [], options = {}) => {

innerFork(true);

const killRunningChild = async signal => {
runChild.removeAllListeners('message');
if (isWin) {
await new Promise(resolve => {
if (!runChild || runChild.exitCode !== null) {
// has exited
resolve();
// 从参数中获取超时时间,默认 2000ms
const killTimeout = (() => {
const index = runArgs.indexOf('--kill-timeout');
if (index !== -1 && runArgs[index + 1]) {
const timeout = parseInt(runArgs[index + 1], 10);
return isNaN(timeout) ? 2000 : timeout;
}
return 2000;
})();

const killRunningChild = async () => {
if (!runChild || runChild.exitCode !== null) {
// 进程已退出
debug('child process already exited');
return;
}

return new Promise(resolve => {
const now = Date.now();
debug(`send SIGINT to child process ${runChild.pid}`);
// 发送退出消息给子进程
runChild.send({
title: 'server-kill',
});

// 设置超时处理
const timeoutHandle = setTimeout(() => {
try {
// 超时后强制结束进程
debug(
`send SIGKILL to child process ${runChild.pid} +${
Date.now() - now
}ms`
);
runChild.kill('SIGKILL');
} catch (err) {
debug(
`send SIGKILL to child process error, msg = ${err.message}, pid = ${runChild.pid}`
);
}
runChild.once('exit', (code, signal) => {
resolve();
});
runChild.send({
title: 'server-kill',
});
}, killTimeout);

// 监听进程退出
runChild.once('exit', () => {
debug(
`child process ${runChild.pid} exited +${Date.now() - now}ms`
);
clearTimeout(timeoutHandle);
resolve();
});
} else {
runChild.kill(signal);
}
});
};

return {
async kill(signal) {
await killRunningChild(signal);
async kill() {
await killRunningChild();
},
async restart() {
// 杀进程
Expand Down
8 changes: 8 additions & 0 deletions lib/wrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ const { join, isAbsolute } = require('path');
const { CHILD_PROCESS_EXCEPTION_EXIT_CODE } = require('./constants');
// eslint-disable-next-line node/no-unsupported-features/node-builtins
const inspector = require('inspector');
const { debuglog } = require('util');

function debug(msg) {
debuglog('[mwtsc]: ' + msg);
};

const log = debuglog('midway:debug');

if (process.debugPort) {
const debugUrl = inspector.url();
Expand Down Expand Up @@ -33,6 +40,7 @@ if (runArgs.includes('--keepalive')) {

process.on('message', data => {
if (data.title === 'server-kill') {
debug('send SIGINT to child process');
process.emit('SIGINT');
}
});
Expand Down
2 changes: 1 addition & 1 deletion test/index.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const { join, resolve } = require('path');
const { unlink } = require('fs/promises');
const { existsSync, writeFileSync, readFileSync } = require('fs');
const { existsSync, writeFileSync, readFileSync } = require('fs');
const { forkRun } = require('../lib/process');
const { execa, sleep, removeFile } = require('./util');
const fetch = require('node-fetch');
Expand Down

0 comments on commit 6aeb30f

Please sign in to comment.