Files
liberama/server/db/JembaDb/JembaDbThread.js
2021-11-24 14:15:09 +07:00

119 lines
2.6 KiB
JavaScript

const { Worker } = require('worker_threads');
const utils = require('./utils');
const JembaDbChild = require('./JembaDbChild');
/* API methods:
openDb
closeDb
create
drop
open
openAll
close
closeAll
tableExists
getInfo
getDbSize
select
insert
update
delete
esc
*/
class JembaDbThread {
constructor() {
this.worker = null;
this.listeners = new Map();
this.requestId = 0;
const apiMethods = [
'create', 'drop', 'open', 'openAll', 'close', 'closeAll',
'tableExists', 'getDbInfo', 'getDbSize', 'select', 'insert', 'update', 'delete', 'dumpTables'
];
for (const action of apiMethods) {
this[action] = async(query) => this._action(action, query);
}
}
_terminate() {
if (this.worker) {
for (const listener of this.listeners.values()) {
listener({error: 'Worker terminated'});
}
this.worker.terminate();
}
this.worker = null;
}
_runWoker() {
//const worker = new Worker(`${__dirname}/JembaDbChild.js`);
const worker = new Worker(JembaDbChild, {eval: true});
worker.on('message', (mes) => {
const listener = this.listeners.get(mes.requestId);
if (listener)
listener(mes);
});
worker.on('error', (err) => {
console.error(err);
});
worker.on('exit', () => {
this._terminate();
});
this.worker = worker;
}
_action(action, query) {
return new Promise((resolve, reject) => {
this.requestId++;
const requestId = this.requestId; //!!!
this.listeners.set(requestId, (mes) => {
this.listeners.delete(requestId);
if (mes.error)
reject(new Error(mes.error));
else
resolve(mes.result);
});
if (this.worker) {
this.worker.postMessage({requestId: this.requestId, action, query});
} else {
reject(new Error('Worker does not exist (database closed?)'));
}
});
}
async openDb(query = {}) {
if (!this.worker) {
this._runWoker();
} else {
throw new Error('Worker has been created already');
}
return this._action('openDb', query);
}
async closeDb() {
const result = await this._action('closeDb');
this._terminate();
//console.log('DB closed');
return result;
}
esc(obj) {
return utils.esc(obj);
}
}
module.exports = JembaDbThread;