SqliteConnectionPool.js 2.2 KB

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