Правильный способ реализации единого пула БД в экспресс-приложении - PullRequest
1 голос
/ 03 мая 2019

Примечание. Эта проблема в основном связана с одноэлементными объектами в узле, а не с пулами БД

Я создаю приложение expressjs, используя модуль узла mysqljs для соединений с БД. Я хочу создать один объект пула, который можно повторно использовать в приложении (для разных моделей и т. Д.). Я хочу знать, как правильно использовать один экземпляр объекта в экспресс-приложении

Я видел много примеров, когда люди создают файл db.js или файл pool.js и требуют его там, где они нужны

// db.js
var mysql = require('mysql');
var pool;
module.exports = {
    getPool: function () {
      if (pool) return pool;
      pool = mysql.createPool(dbConfig);
      return pool;
    }
};

// app.js
var pool = require('pool').getPool();
pool.query('SELECT * FROM users');

Однако я чувствую, что это все-таки неправильный подход, поскольку вы полагаетесь на кеш nodejs, чтобы возвращать один и тот же экземпляр каждый раз, когда вам требуется объект. Если бы узел заканчивал тем, что загружал код дважды, вы бы получили два пула, например

const poolA = require('./pool').getPool();
const poolB = require('./POOL').getPool(); // resolves to same file but node will not get result from cache

console.log(poolA === poolB); // false

Из большинства вещей, которые я прочитал, как правило, не рекомендуется использовать одноэлементные объекты в приложениях вашего узла из-за такого поведения, но это похоже на распространенный вариант использования для приложений Express. Поэтому мне было интересно, как люди создают свой единый пул на протяжении всего срока службы приложения?

Примечание. В данный момент я выполняю создание экземпляра пула в корне приложения, а затем передаю экземпляр в качестве параметра функции конструктора, но мне это тоже не нравится

1 Ответ

0 голосов
/ 04 мая 2019

Короткий ответ

Я не вижу проблем в вашем коде.

Длинный ответ

Это решение при условии, что на самом деле у вас нет файла с именем POOL.js с таким же точным кодом.

Ниже require разрешается в тот же файл, что и pool.js, потому что вы 'используется файловая система с включенной case-insensitivity.Например NTFS или APFS.

const poolB = require('./POOL').getPool();

Если вы используете case sensitive файловую систему, такую ​​как ext4, то вы получите сообщение об ошибке.

Error: Cannot find module './POOL'

Внутренне node кэширует файлы на основе указанного вами пути к файлу,Из source :

const relativeResolveCache = Object.create(null);

relResolveCacheIdentifier = `${parent.path}\x00${request}`;
const filename = relativeResolveCache[relResolveCacheIdentifier];

if (filename !== undefined)
...

Поскольку JavaScript - это case-sensitive, объект (cache, сверху) со свойством (simplefying) pool и POOLбудет отличаться и будет ссылаться на полностью две разные ссылки на объект.

Заключение

Следите за gotchas с именами файлов или именами идентификаторов.

...