如何完全关闭node-mongodb-native 3.1中的MongoDB连接+套接字?

时间:2019-01-16 13:19:48

标签: node.js mongodb jestjs

简而言之::当我尝试在Node.js中关闭MongoDB连接时,MonogDB驱动程序似乎已按预期关闭了连接本身,但是后台中的某些东西似乎在等待套接字直到它关闭(大约)超时,这会阻止像Jest这样的事情彻底结束。

魔鬼:

我正在使用NPM软件包"mongodb": "^3.1.11"(Node.js MongoDB Driver 3.1)和"jest": "^23.6.0",并且我知道您应该在测试完成后关闭连接。

MongoDB example by Jest当前似乎与Node.js MongoDB Driver 2.x相关,并且版本3不再具有db.close()方法。

这是我的简单测试文件:

// example.test.js
const { MongoClient } = require('mongodb');

let client;
let db;

beforeAll(async () => {
    client = await MongoClient.connect('mongodb://localhost:27017', {
        useNewUrlParser: true,
    });
    db = await client.db('testdb');
});

afterAll(async () => {
    await client.close(); // Returns successfully
});

it('should insert and find document', async () => {
    const collection = db.collection('files');
    await collection.insert({name: 'Jest'});
    const doc = await collection.findOne({name: 'Jest'});
    expect(doc._id).toBeDefined();
    expect(doc.name).toBe('Jest');
});

测试完成后,MongoDB连接显然已成功关闭。我什至可以通过检查MongoDB服务器日志(end connection 127.0.0.1:33312 (0 connections now open))来确认这一点,但Jest仍然拒绝结束该过程。推荐的Jest CLI选项--detectOpenHandles不输出任何内容。

我意识到6分钟后Jest最终会成功结束; 6分钟=== 360000毫秒,恰好是socketTimeoutMS optionsMongoClient.connect的默认值。

如果我为socketTimeoutMS设置了自定义值,则Jest将在指定时间后完成。从上方编辑测试文件:

// ...
beforeAll(async () => {
    client = await MongoClient.connect('mongodb://localhost:27017', {
        useNewUrlParser: true,
        socketTimeoutMS: 1000, // <----- insert this line
    });
    db = await client.db('testdb');
});
// ...

现在,Jest将在仅延迟1秒而不是6分钟后完成。

我不知道套接字超时在这里真正做什么,以及为什么MongoDB驱动程序在关闭连接后等待套接字超时。可能是驱动程序中的错误,也可能是我做错了。

我还发现,使用force方法(close)的client.close(true)选项似乎可以在本地(MacOS)解决此问题,但不幸的是,在CI服务器上(Linux) / Docker)。 Jest CLI选项--forceExit也是如此。

有什么想法可以干净地关闭MongoDB连接吗?

0 个答案:

没有答案