使用MongoDB连接池的NodeJS一次性脚本 - 如何终止?

时间:2015-01-09 10:40:04

标签: javascript node.js mongodb

我知道在NodeJS中使用单一数据库连接类型的MongoDB连接池的最佳实践

var db = null;

var connection = function getDBConnection(callback) {
    if(db) { callback(null, db) } else { MongoClient.connect( .... )  }
}

module.exports = getDBConnection;

然而,我现在无法理解的是如何在一次性脚本中处理这个问题,例如,对某个db集合的文档进行一些预初始化:

getDBConnection(function (err, database) {
    var collection = database.collection("objects");

    var allObjectsArray = collection.find( /* ... */ 
    ).toArray(function (err, objects) {

        if(err != null) console.log(err);
        assert.equal(null, err);

        _.each(objects, function (item) {

            collection.update(
                { id:  item.id},
                { $set: { /* ... */ }},

                function (err, result) {
                    if(err != null) console.log(err);
                    assert.equal(null, err);
                }
            );

        });

        // database.close(); <-- this fails with "MongoError: Connection Closed By Application", thrown by the update callback

    });
    // database.close(); <-- this fails too, thrown by the toArray callback
});

如果我这样调用脚本,由于仍然打开连接,它永远不会终止。如果我关闭底部的连接,它会因为关闭连接而失败。

考虑到为每次更新打开一个新连接不是一个真正的选择,我错过了什么?保持连接打开对于webapps来说可能没问题,但对于从shell脚本调用的一次性脚本,这确实没有用,是吗?

对不起,如果以前出现过这个问题,我已经给了它一些研究,但还没能为我找到一个合适的答案......

谢谢! 儒略

1 个答案:

答案 0 :(得分:0)

作为一个&#34;汇集连接&#34;如果在驱动程序连接下需要,则运行代码以保持连接活动并在池中建立更多连接。非常像各种服务器代码&#34;方法,事件循环处理程序已被调用,并且在代码结束之前,进程不会退出,直到取消注册。

因此,在执行完所有代码后调用的两个选项是:

  1. 完成所有操作后,专门致电db.close()或在代码上下文中database.close()

  2. 调用process.exit()这是node.js应用程序中的通用调用,它将关闭整个进程并因此停止任何其他当前事件循环代码。这实际上为您提供了一个在退出时抛出错误的选项,如果您希望您的代码是&#34; shell集成&#34;某处,寻找退出状态。

  3. 或者两个都打电话。 db.close()将允许执行下一行代码,无论你放在哪里,也会运行。

    但是你必须等到所有东西都被调用,所以你不能在中间使用异步代码的同步循环:

    async.each(objects,function(item,callback) {
        collection.update(
           { "_id": item._id },
           {
              // updates
           },
           callback
        );
    },function(err) {
        if (err) throw err;
        database.close();
    });