猫鼬和指挥官

时间:2012-04-27 18:30:38

标签: node.js mongodb mongoose

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

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

我发现允许我关闭的唯一事情是使用process.exit(),但我不愿意终止该过程。我是否应该采取一些特别的措施来触发优雅的关闭?

3 个答案:

答案 0 :(得分:0)

我对API docs的阅读意味着.disconnect() 必须才能获得回调函数。看起来每个被断开连接都会被调用,并且可能会传递错误。

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

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

(我对Mongoose的了解越多,我就越想在MongoDB客户端周围编写一个薄的包装器,所以我不必处理Mongoose的“帮助”。)

答案 1 :(得分:0)

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

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

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

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()来电就可以很好地解决问题!

答案 2 :(得分:0)

我使用async“Series”执行操作,然后在完成时调用 mongoose.connection.close()。它可以防止回调地狱,并允许您在所有其他方法完成后,一次一个地执行操作,或者并行执行操作,然后执行操作。我一直使用它来处理需要mongoose的脚本,但是要在所有mongoose操作完成后终止。