1

我正在编写一些脚本,用于使用 commands.js 对Mongoose模型进行一些命令行操作(最终,我想使用Cron运行这些工具)。

现在,我已经编写了几个脚本,commander它们都可以正常工作,但是如果我使用 连接到 MongoDB 数据库mongoose,它们的脚本在完成后就会挂起。现在,我认为数据库连接使节点保持活动状态,所以我添加了mongoose.disconnect()一行,它仍然挂起。

我发现唯一可以让我关闭的是使用process.exit(),但我不愿意仅仅终止该过程。我应该做些什么来触发正常关机吗?

4

3 回答 3

0

我对API 文档的阅读意味着.disconnect() 必须给它一个回调函数。看起来它是为每个断开连接的并且可能会传递一个错误而调用的。

代码中有一个检查,以确保当事情解决时它不存在时它不会被调用,但是该检查没有在错误时运行,所以如果 Mongoose 收到来自 MongoDB 客户端的错误消息,它可能是保持连接打开,这就是它没有停止执行的原因。

如果您只打开到数据库的单个连接,您可能只想调用[Connection object].close(),因为如果没有给出回调,该函数会正确插入一个无操作“回调”,并且看起来它会正确破坏事物。

(我对 Mongoose 的研究越多,我就越想围绕 MongoDB 客户端编写一个瘦包装器,这样我就不必处理 Mongoose 的“帮助”。)

于 2012-04-27T18:53:03.117 回答
0

直接关闭节点程序是隐藏症状,而不是解决问题!

我终于隔离了这个问题,发现它与 Mongoose 模式定义有关。如果您在定义 Mongoose 模式后过早关闭连接1,应用程序将挂起并最终产生一些与 MongDB 相关的奇怪错误。

program.parse(argv)在运行命令应用程序之前添加一个小的超时可以解决问题。只需像这样包装代码:

var program  = require('commander')
  , mongoose = require('mongoose')
  , models   = null
;

// Define command line syntax.
program
  .command(...)
;

mongoose.connect(
    ..., // connection parameters.

    function() {
        // connected to database, defined schemas.
        models = require('./models');

        // Wait 1 second before running the application code.
        setTimeout(function(){
            program.parser(process.argv);
        }, 1000);
    }
);

1:这是我最初的解释,我还没有(还)广泛地测试过这个理论。但是,从应用程序中删除 Mongoose 模式定义成功地防止了应用程序挂起。


实际上,只需使用process.nextTick()而不是setTimeout()调用就可以很好地解决这种情况!

于 2012-04-28T21:16:24.813 回答
0

我使用异步“系列”来执行操作,然后在完成时调用mongoose.connection.close()。它可以防止回调地狱,并允许您巧妙地一次执行一个操作,或者在所有其他方法完成后并行执行一个函数。我一直将它用于需要 mongoose 但要在所有 mongoose 操作完成后终止的脚本。

于 2012-07-19T23:53:58.863 回答