SqliteConnectionPool.js 2.1 KB

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