Улучшения SqliteConnectionPool

This commit is contained in:
Book Pauk
2021-02-01 18:05:32 +07:00
parent a09b70a991
commit 6c20b0b83e
2 changed files with 31 additions and 31 deletions

View File

@@ -4,8 +4,6 @@ const SqliteConnectionPool = require('./SqliteConnectionPool');
const log = new (require('../core/AppLogger'))().log;//singleton
const migrations = {
'app': require('./migrations/app'),
'readerStorage': require('./migrations/readerStorage'),
};
let instance = null;
@@ -32,11 +30,11 @@ class ConnManager {
const dbFileName = this.config.dataDir + '/' + poolConfig.fileName;
//бэкап
if (await fs.pathExists(dbFileName))
if (!poolConfig.noBak && await fs.pathExists(dbFileName))
await fs.copy(dbFileName, `${dbFileName}.bak`);
const connPool = new SqliteConnectionPool();
await connPool.open(poolConfig.connCount, dbFileName);
await connPool.open(poolConfig, dbFileName);
log(`Opened database "${poolConfig.poolName}"`);
//миграции

View File

@@ -1,27 +1,32 @@
const sqlite = require('sqlite');
const SQL = require('sql-template-strings');
const utils = require('../core/utils');
const waitingDelay = 100; //ms
class SqliteConnectionPool {
constructor() {
this.closed = true;
}
async open(connCount, dbFileName) {
if (!Number.isInteger(connCount) || connCount <= 0)
return;
async open(poolConfig, dbFileName) {
const connCount = poolConfig.connCount || 1;
const busyTimeout = poolConfig.busyTimeout || 60*1000;
const cacheSize = poolConfig.cacheSize || 2000;
this.dbFileName = dbFileName;
this.connections = [];
this.freed = new Set();
this.waitingQueue = [];
for (let i = 0; i < connCount; i++) {
let client = await sqlite.open(dbFileName);
client.configure('busyTimeout', 10000); //ms
client.configure('busyTimeout', busyTimeout); //ms
await client.exec(`PRAGMA cache_size = ${cacheSize}`);
client.ret = () => {
this.freed.add(i);
if (this.waitingQueue.length) {
this.waitingQueue.shift().onFreed(i);
}
};
this.freed.add(i);
@@ -30,30 +35,27 @@ class SqliteConnectionPool {
this.closed = false;
}
_setImmediate() {
get() {
return new Promise((resolve) => {
setImmediate(() => {
return resolve();
if (this.closed)
throw new Error('Connection pool closed');
const freeConnIndex = this.freed.values().next().value;
if (freeConnIndex !== undefined) {
this.freed.delete(freeConnIndex);
resolve(this.connections[freeConnIndex]);
return;
}
this.waitingQueue.push({
onFreed: (connIndex) => {
this.freed.delete(connIndex);
resolve(this.connections[connIndex]);
},
});
});
}
async get() {
if (this.closed)
return;
let freeConnIndex = this.freed.values().next().value;
if (freeConnIndex == null) {
if (waitingDelay)
await utils.sleep(waitingDelay);
return await this._setImmediate().then(() => this.get());
}
this.freed.delete(freeConnIndex);
return this.connections[freeConnIndex];
}
async run(query) {
const dbh = await this.get();
try {