我从db表和solr读取数据后编写了一个脚本来更新我的db表。我正在使用asyn.waterfall模块。问题是成功完成所有操作后脚本不会退出。我已经使用了数据库连接池,也认为可能会创建无限期等待的脚本。 我想把这个脚本放在crontab中,如果它不能正常退出,那就会不必要地创建很多实例。
答案 0 :(得分:43)
我刚刚解决了这个问题。
使用process.exit()
的问题是我正在处理的程序是创建句柄,但从不销毁它们。
正在处理目录并将数据放入 orientdb 。
所以我要学习的一些事情是在删除引用之前需要关闭数据库连接。并且process.exit()
并未解决所有情况。
当我的项目处理了2,000个文件时。它会下降到大约500左右,额外的句柄将填满可用的工作内存。这意味着它无法继续。因此,最后永远不会到达process.exit
。
另一方面,如果您关闭请求应用保持打开的项目,您可以从源头解决问题。
我能够使用的两个“未记载的函数”是
process._getActiveHandles();
process._getActiveRequests();
我不确定其他哪些功能可以帮助调试这些类型的问题,但这些功能真是太棒了。
他们返回一个数组,你可以通过使用这些方法确定你的过程中发生了什么。
我希望这可以帮助其他任何人绊倒这篇文章。
答案 1 :(得分:22)
通过调用
,您必须在完成后告诉它process.exit();
更具体地说,您希望在async.waterfall()(该函数的第二个参数)的回调中调用它。此时,所有异步代码都已执行,您的脚本应准备好退出。
编辑:正如下面@Aaron所指出的,这可能与数据库连接处于活动状态,以及不允许节点进程结束等事情有关。答案 2 :(得分:4)
我们可以使用:
退出执行connection.destroy();
答案 3 :(得分:3)
您可以使用节点模块why-is-node-running:
1)运行npm install -D why-is-node-running
2)在代码中添加import * as log from 'why-is-node-running';
3)当您希望程序退出时,添加一条日志语句:
afterAll(async () => {
await app.close();
log();
}
这将打印带有堆栈跟踪的打开句柄列表,以找出它们的起源:
There are 5 handle(s) keeping the process running
# Timeout
/home/maf/dev/node_modules/why-is-node-running/example.js:6 - setInterval(function () {}, 1000)
/home/maf/dev/node_modules/why-is-node-running/example.js:10 - createServer()
# TCPSERVERWRAP
/home/maf/dev/node_modules/why-is-node-running/example.js:7 - server.listen(0)
/home/maf/dev/node_modules/why-is-node-running/example.js:10 - createServer()
答案 4 :(得分:2)
如果您使用Visual Studio代码,则可以直接附加到已经运行的Node脚本。
首先,运行 Debug:附加到节点进程命令:
调用该命令时,VS Code将提示您将哪个Node.js进程附加到:
您的终端应显示以下消息:
Debugger listening on ws://127.0.0.1:9229/<...>
For help, see: https://nodejs.org/en/docs/inspector
Debugger attached.
然后,在调试控制台中,您可以使用The Lazy Coder’s answer中的代码:
process._getActiveHandles();
process._getActiveRequests();