SqliteConnectionPool.js 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. const Promise = require('bluebird');
  2. const utils = require('./utils');
  3. const sqlite = require('sqlite');
  4. const waitingDelay = 100; //ms
  5. class SqliteConnectionPool {
  6. constructor(connCount, logger, config) {
  7. this.config = config;
  8. this.connCount = connCount;
  9. }
  10. async init() {
  11. this.logger.log('Opening database');
  12. utils.mkDirIfNotExistsSync(config.dataDir);
  13. const dbFileName = config.dataDir + '/' + config.dbFileName;
  14. this.connections = [];
  15. this.taken = new Set();
  16. this.freed = new Set();
  17. for (let i = 0; i < this.connCount; i++) {
  18. let client = await sqlite.open(dbFileName);
  19. client.configure('busyTimeout', 10000); //ms
  20. client.ret = () => {
  21. this.taken.delete(i);
  22. this.freed.add(i);
  23. };
  24. this.freed.add(i);
  25. this.connections[i] = client;
  26. }
  27. }
  28. _setImmediate() {
  29. return new Promise((resolve) => {
  30. setImmediate(() => {
  31. return resolve();
  32. });
  33. });
  34. }
  35. async get() {
  36. if (this.closed)
  37. return;
  38. let freeConnIndex = this.freed.values().next().value;
  39. if (freeConnIndex == null) {
  40. if (waitingDelay)
  41. await utils.sleep(waitingDelay);
  42. return await this._setImmediate().then(() => this.get());
  43. }
  44. this.freed.delete(freeConnIndex);
  45. this.taken.add(freeConnIndex);
  46. return this.connections[freeConnIndex];
  47. }
  48. async run(query) {
  49. const dbh = await this.get();
  50. try {
  51. let result = await dbh.run(query);
  52. dbh.ret();
  53. return result;
  54. } catch (e) {
  55. dbh.ret();
  56. throw e;
  57. }
  58. }
  59. async all(query) {
  60. const dbh = await this.get();
  61. try {
  62. let result = await dbh.all(query);
  63. dbh.ret();
  64. return result;
  65. } catch (e) {
  66. dbh.ret();
  67. throw e;
  68. }
  69. }
  70. async close() {
  71. for (let i = 0; i < this.connections.length; i++) {
  72. await this.connections[i].close();
  73. }
  74. this.closed = true;
  75. }
  76. }
  77. module.exports = SqliteConnectionPool;