【问题标题】:Mongoose and commander猫鼬和指挥官
【发布时间】:2013-11-05 01:43:13
【问题描述】:

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

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

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

【问题讨论】:

    标签: node.js mongodb mongoose


    【解决方案1】:

    我对@9​​87654321@ 的解读意味着.disconnect() 必须 被赋予一个回调函数。看起来它是为每个断开的连接调用的,并且可能会传递一个错误。

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

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

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

    【讨论】:

    • 我不明白你的第一段。您链接到的 API 文档清楚地说:“param: Function optional callback”。此外,如果我通过 function(error){...}function(){...},我会得到一个堆栈跟踪,其中包含“TypeError:对象不是函数。”。
    • 他们声称它是可选的,但阅读它正在谈论的右侧的代码。如果发生错误,它不会检查是否实际提供了该功能。 if(err) return fn(err) 出现在之前 if(fn)
    • 是的,抱歉,我阅读速度很慢 :-) 我添加了更多诊断信息,连接已关闭且没有错误(err 值为 undefined)。但是,我最终从 MongoDB 核心中得到了一些其他错误,所以我不知道这是否解决了我的问题。当我有更多细节时,我会保持联系。
    • 嗨,大卫,感谢您的回答。不幸的是,这并不能解决问题,但我会在 Mongoose 问题跟踪器中报告这个错误。
    • 我只是在 Mongoose 问题跟踪器上reported this issue
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

      我终于隔离了问题,发现它与 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() 调用就可以很好地解决这种情况!

      【讨论】:

        猜你喜欢
        • 2019-02-05
        • 2010-11-24
        • 2014-12-06
        • 1970-01-01
        • 1970-01-01
        • 2016-05-10
        • 1970-01-01
        • 1970-01-01
        • 2017-01-06
        相关资源
        最近更新 更多