【问题标题】:How do I catch *and ignore* SIGINT in Node.js?如何在 Node.js 中捕获 * 并忽略 * SIGINT?
【发布时间】:2021-10-17 14:37:03
【问题描述】:

我发现了一篇关于相关主题的不同帖子 (How to perform an async operation on exit),但它可能不适用于 macOS,或者在运行 Node.js v14 时不再适用。

我最初的问题更复杂。我无法让 setTimeouts 或 await 在 SIGINT 的回调(或异步回调)中正常工作。但后来我意识到我真正需要做的,首先是能够捕获并忽略 SIGINT。

如果我能做到这一点,那么我也可以在需要时关闭以响应 SIGINT。

所以我回到了基础,看看我是否可以简单地禁用 SIGINT。我做不到。

我可以检测到 SIGINT,我可以使用控制台消息或任何其他同步代码进行响应,但是无论我做什么,我的代码都会关闭,并且很快就会关闭。

process.on('SIGINT', () => { console.log('here'); return false; });
process.on('SIGINT', () => { console.log('here'); return true; });
process.on('SIGINT', () => { console.log('here'); return undefined; });
process.on('SIGINT', () => { console.log('here'); return new Promise(resolve => { console.log(resolve); }); });

这些方法都不能阻止我的 Node.js 服务器在按下 Ctrl+C 或以其他方式向进程发送 SIGINT 后关闭。

更新:

当我通过node app.js 运行我的服务器时,SIGINT 拦截正常工作!

显然,通过nodemon 间接运行我的服务器应用程序的工件让我发疯了。来自我的 IDE 终端的 Ctrl+C 或使用 IDE 的图形红色发送的中断 ???? (stop) 按钮无法正确捕获,因为结果信号确实被发送到 nodemon。然而,在 IDE 环境之外,没有 nodemon 解决问题,我的优雅关闭可以按我的意愿工作。

【问题讨论】:

  • 如果有人在他们的节点脚本中运行 puppeteer,请确保在启动浏览器时将 handleSIGINT 设置为 falseawait puppeteer.launch({ handleSIGINT: false, ...}) 导致 puppeteer 在 SIGINT 上调用 process.exit()。

标签: javascript node.js sigint graceful-shutdown


【解决方案1】:

如果您观察到这种意外关机行为,请始终思考“谁在发送什么信号?”。 根据操作系统和其他进程,可能会发送许多其他信号,例如参见How does SIGINT relate to the other termination signals such as SIGTERM, SIGQUIT and SIGKILL?

在您的情况下,最有可能发生的是nodemon 进程在SIGINT 之后发送SIGKILL。存在几个不能中止的此类信号。 nodemon 允许通过--signal 控制默认终止信号,请参阅https://github.com/remy/nodemon/blob/master/doc/cli/options.txtnodemon 也可以通过本地和全局配置文件进行配置,参见https://github.com/remy/nodemon/blob/master/doc/cli/config.txt

【讨论】:

  • 我还没有研究过,但我希望有一种方法可以控制 nodemon 发送的信号。如果我可以告诉 nodemon 只发送 SIGINT,或者,如果它坚持发送 SIGKILL,它至少允许我配置延迟,那就太好了。
  • 确实有。我在上面的回复中添加了解决方案。如果这不能解决您的问题,其他进程(例如 IDE)可能正在发送信号。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-09
  • 1970-01-01
  • 1970-01-01
  • 2011-02-02
  • 2013-12-28
  • 2022-09-23
  • 1970-01-01
相关资源
最近更新 更多