Ошибка открытой обработки Jest TLSWRAP с использованием простого пула узлов postgres.query() исправлена с задержкой setTimeout, но почему?

#node.js #express #jestjs #node-postgres

Вопрос:

Когда я запускаю следующий тест:

 afterAll(async () => {
    await runDbBuild();
    await pool.end();
});

describe("queries.newteetypes.select.all():", () => {
        test("Test 1: object keys ", async () => {
            const awaitedResponse = await queries.newteetypes.select.all();
            expect(awaitedResponse).toStrictEqual(anticipatedResponse);
    });
});
 

Я получаю эту ошибку: Jest has detected the following 1 open handle potentially keeping Jest from exiting:
скриншот ошибки

Приведенный выше код, который показан, работает абсолютно нормально в рабочей среде. Проблема заключается только в jest том, что я получаю предупреждение о потенциальных открытых дескрипторах.

Я могу это исправить, введя задержку с setTimeout() помощью and Promise , но размещение сбивает меня с толку. Вот решение (тот же код, но с добавлением одной строки над вызовом запроса):

 afterAll(async () => {
    await runDbBuild();
    await pool.end();
});

describe("queries.newteetypes.select.all():", () => {
        test("Test 1: object keys ", async () => {
            await new Promise((resolve) => setTimeout(() => resolve(), 2000)); // Putting a delay before the query solves the problem, but putting the delay after the query doesn't resolve it.
            const awaitedResponse = await queries.newteetypes.select.all();
            expect(awaitedResponse).toStrictEqual(anticipatedResponse);
    });
});
 

Мне это кажется очень нелогичным. Изначально я пытался ввести тайм-аут в afterAll() функцию, но это не имело никакого значения, независимо от того, где я его включил. Затем я поэкспериментировал, поместив ее после вызова запроса в test() функцию, но это не сработало. Когда я помещаю ее перед вызовом запроса, я перестаю получать ошибку. Но почему это может иметь значение?

Комментарии:

1. Вау, я борюсь именно с этой проблемой. Пока я не нашел ничего, что могло бы помочь, НО вставка вашего 2-секундного таймера над моим pool.connect() решила проблему. Очень, очень странно. Во всяком случае, я думаю, что это помогает сузить проблему с подключением по сравнению с проблемой запроса.

Ответ №1:

Рассматривайте свой «новый пул (…)» как обещание и await для него:

 async function createPool () {
  return await new Pool({ connectionString })
}
 

Ваши выводы setTimeout заставили меня попробовать это с тем же успешным результатом:

 await process.nextTick(() => {})
 

Размещение этого прямо перед моим connect() сработало. Итак, оттуда я начал резервное копирование до «самой ранней» точки, в которой добавление a process.nextTick устранило бы проблему, и, похоже, ее можно решить, просто рассматривая new Pool(..) как обещание.

Возможно, пул готов начать раздавать клиентов, прежде чем он будет полностью готов отслеживать их под капотом? Возможно, именно поэтому дополнительный await фронт решает эту проблему.

Это может быть связано с тем, почему люди не могут правильно закрыть клиентов или пул — потому что что-то в управлении пулом искажено. Например: https://github.com/brianc/node-postgres/issues/2341

Комментарии:

1. Ах, я так рад, что я не одинок в этом! Я проверю ваше решение, когда буду смотреть на серверную часть в следующий раз. Спасибо, что поделились — я дам вам знать, как это происходит!

2. Да, было бы полезно узнать, устраняет ли это вашу проблему. Я опубликовал некоторые комментарии на сайте github: github.com/brianc/node-postgres/issues/2648