Вкратце: Когда я пытаюсь закрыть соединение MongoDB в Node.js, драйвер MonogDB, по-видимому, закрывает само соединение, как и ожидалось, но что-то в фоновом режиме, кажется, ждет сокета до тех пор, пока не истечет время out (или около того), что мешает чистому завершению таких вещей, как Jest.
Deatils:
Я использую пакеты NPM "mongodb": "^3.1.11"
(Node.js MongoDB Driver 3.1) и "jest": "^23.6.0"
, и я знаю, что вам следует закрыть соединение после завершения испытаний.
Пример MongoDB от 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 минут Шут все-таки успешно закончится; 6 минут === 360000 миллисекунд, что является значением по умолчанию для socketTimeoutMS
из MongoClient.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?