【问题标题】:Not sure why node is continuously running不知道为什么节点会持续运行
【发布时间】:2020-02-04 00:58:13
【问题描述】:

我不明白为什么这个应用程序一直在运行。我试过使用 why-is-node-running 包,但我不完全确定如何正确读取输出。这是它的第一个输出:

There are 30 handle(s) keeping the process running
    # TCPWRAP
    /node_modules/mongodb/lib/core/connection/connect.js:269 - socket = tls.connect(parseSslOptions(family, options));
    /node_modules/mongodb/lib/core/connection/connect.js:29  - makeConnection(family, options, cancellationToken, (err, socket) => {
    /node_modules/mongodb/lib/core/sdam/monitor.js:182       - connect(monitor.connectOptions, monitor[kCancellationToken], (err, conn) => {
    /node_modules/mongodb/lib/core/sdam/monitor.js:206       - checkServer(monitor, e0 => {
    /node_modules/mongodb/lib/core/sdam/monitor.js:92        - monitorServer(this); 

我的猜测是它与 MongoDB 没有正确关闭有关。虽然,当我在打开客户端和关闭客户端之间删除所有其他功能时,它完美地打开和关闭。

在末尾添加process.exit() 可以正确关闭程序,但我想弄清楚为什么它没有关闭。

该应用程序的摘要是它正在从 MongoDB 获取数据,清理它,然后将其写入 Firestore - 所以很多异步操作正在进行,但我没有看到与 Firestore 相关的东西弹出为什么节点运行日志。

const GrabStuffFromDBToCalculate = require("./helpers/GrabStuffFromDBToCalculate");
const SendToFirestore = require("./helpers/SendToFirestore");
const log = require("why-is-node-running");
const { MongoClient } = require("mongodb");
require("dotenv").config();

const main = async () => {
  try {
    const client = await MongoClient.connect(process.env.MONGODB_URI, {
      useNewUrlParser: true,
      useUnifiedTopology: true
    });
    const collection = await client.db("test").collection("testcollection");
    const trip_object = await GrabStuffFromDBToCalculate(collection);
    SendToFirestore(trip_object);
    client.close();
    log(); // "There are 30 handle(s) keeping the process running including node_modules/mongodb/lib/core/connection/connect.js:269 - socket = tls.connect(parseSslOptions(family, options));"
    // process.exit() // this closes everything but I'd rather not have to use this
  } catch (err) {
    console.log(err);
    client.close();
  }
};

const runAsync = async () => {
  await main(); // this exists because I'm usually running multiple main() functions
};

runAsync();

SendToFirestore 代码:

const firebase = require("firebase");
const firebaseConfig = require("../config");

module.exports = SendToFirestore = trip_object => {
  if (!firebase.apps.length) {
    firebase.initializeApp(firebaseConfig);
  }
  const db = firebase.firestore();
  db.doc(`hello/${object._id}`).set({
    objectid:object._id
  });
};

GrabStuffFromDBToCalculate 代码(简化方式):

module.exports = GrabStuffFromDBToCalculate = async collection => {
  const cursor = await collection
    .aggregate([

        // does a bunch of stuff here

    ])
    .toArray();
  const newObj = cursor[0];
  return newObj;
};

【问题讨论】:

  • 似乎还有更多可以看到,例如SendToFirestore()GrabStuffFromDBToCalculate() 的代码。此外,您应该在await client.close() 之后调用log(),以便您确定在log() 列出打开的句柄之前完成。
  • 另外,log() 不会向您显示仍然打开的实际句柄吗?你能和我们分享一下这个输出吗?
  • 请编辑问题以显示显示问题的完整、最少的代码。你所拥有的是隐藏了太多的细节。 stackoverflow.com/help/minimal-reproducible-example
  • 这是一个小调整,可能无法解决您的问题,但您也可能只想将 client.close() 放在 finally 块中,而不是 catch(和主块)。这保证它是在您的应用程序中的任何分支之后发生的最后一件事。
  • 我也相信 client 可能不存在于您的 catch 块中。在 try {} 范围之外定义 client

标签: node.js mongodb google-cloud-firestore


【解决方案1】:

将我的评论变成答案,因为它导致了丢失的部分。

节点没有关闭,因为您有一个打开的 Firestore 连接。您必须调用 terminate 以允许 SDK 关闭和释放资源:

db.terminate();

这与允许 nodejs 自动关闭有关。


另外,我不确定你是否理解我建议你使用await,就像在

await client.close()

在调用log() 之前,您可以确保在进行日志记录之前客户端连接已关闭。 client.close() 是一种异步方法,因此您的原始代码将在关闭完成之前 log()

【讨论】:

  • OP 的代码使用的是 Firestore,而不是实时数据库。
  • @DougStevenson 是的,但概念是一样的:连接是打开的 = 弄清楚如何关闭它。我认为这算是一个答案,尽管我 100% 同意将 db.terminate() 放在答案中会比 firebase.database().goOffline() 更准确。
  • 如果您使用的是 Firestore,您应该使用我的答案中的代码。
  • 我会避免将其标记为正确,因为它可能会在将来误导某人。
  • @mpc75 - 更新为使用终止。
猜你喜欢
  • 2020-09-03
  • 1970-01-01
  • 2021-09-22
  • 1970-01-01
  • 2022-08-21
  • 1970-01-01
  • 1970-01-01
  • 2015-04-23
  • 1970-01-01
相关资源
最近更新 更多