我有一个 Angular 的 npm 构建脚本:
"build": "ng build my-project-name"
此脚本经常挂起(在我们的构建管道内和本地)。我想设置一个时间限制,之后进程将被终止并重新启动。我尝试使用带有
spawn
或 spawnSync
的节点脚本来运行 npm.cmd run build
并显式使用超时或在返回的句柄上调用 .kill()
,看起来进程已被终止,但随后它的输出继续击中终端并且必须手动终止终端。
是否有任何通用方法来运行 NPM 脚本,该脚本将在给定时间后被终止?
这是我最终使用的。
制作一个js脚本
timeout.js
,如下所示:
setTimeout(() => process.exit(1), 20000);
安装节点包
concurrently
像这样制作 NPM 脚本:
{
"build:with-timeout": "concurrently -k \"node timeout.js\" \"npm run build\""
}
使用
-k
标志 concurrently
将在其中一个进程终止时向所有其他进程发送 SIGTERM
信号。在我的具体情况下,我选择通过构建进程监控 CPU 使用情况,如果其活动在 2 分钟内降至接近 0,则终止。
如果脚本生成像笑话这样的子进程,您可以使用以下方法来监视进程并使用 grep 杀死进程。
process-gaurd.js
import args from "command-line-args";
import { execa } from "execa";
import chalk from "chalk";
const optionDefinitions = [
{ name: "timeout", alias: "t", type: Number },
{ name: "process", alias: "p", type: String },
{ name: "killgrep", alias: "k", type: String }
];
const options = args(optionDefinitions);
const timeout = options.timeout;
const process = options.process;
const killGrep = options.killgrep;
const killCommand = killGrep
? `ps aux | grep -E '${killGrep}' | awk '{print $2}' | xargs kill -9`
: "";
const forceKillProcesses = killCommand !== "";
console.log(
chalk.yellow(
`setting ${timeout}s auto kill timeout for running command ${chalk.green(`'${process}'`)}`
)
);
const abortController = new AbortController();
setTimeout(() => {
console.log(
chalk.red(
`timeout exceeded running command ${chalk.bold(`'${process}'`)}. exiting...`
)
);
if (forceKillProcesses) {
console.log(
chalk.red(
`killing all the process associated with it by runniing ${killCommand}`
)
);
execa({
shell: true,
stdio: "inherit",
verbose: "full",
timeout: 2000,
detached: false,
forceKillAfterDelay: true,
cleanup: true
})`${killCommand}`;
}
abortController.abort();
}, timeout * 1000);
try {
execa({
shell: true,
stdio: "inherit",
verbose: "full",
timeout: timeout * 1000,
detached: false,
killSignal: "SIGTERM",
forceKillAfterDelay: true,
cancelSignal: forceKillProcesses ? undefined : abortController,
cleanup: true
})`${process}`;
} catch (err) {
console.log(chalk.red(err));
}
然后运行脚本
node process-gaurd.js -t 600 -p 'npm run test' -k 'react-app-rewired/scripts/test.js|jest'