five-server
Version:
Development Server with Live Reload Capability. (Maintained Fork of Live Server)
112 lines • 3.58 kB
JavaScript
"use strict";
/**
* @author Yannick Deubel (https://github.com/yandeu)
* @copyright Copyright (c) 2021 Yannick Deubel
* @license {@link https://github.com/yandeu/five-server/blob/main/LICENSE LICENSE}
*/
Object.defineProperty(exports, "__esModule", { value: true });
const events_1 = require("events");
const worker_threads_1 = require("worker_threads");
const path_1 = require("path");
const parseBody_1 = require("./parseBody");
/** Handles multiple Workers. */
class WorkerPool extends events_1.EventEmitter {
constructor(script, options = {}) {
super();
this.script = script;
this.options = options;
this.index = 0;
this.workers = [];
this.queue = [];
this.timer = 'idle';
this.terminating = false;
this.logLevel = 1;
const { rateLimit = 50, worker = 1, logLevel = 1, init } = options;
this.rateLimit = rateLimit;
this.worker = worker;
this.logLevel = logLevel;
for (let i = 0; i < this.worker; i++) {
this.create(init);
}
}
async terminate() {
var _a;
this.terminating = true;
await (0, parseBody_1.removeTmpDirectory)((_a = this.options.init) === null || _a === void 0 ? void 0 : _a.cwd);
this.removeAllListeners();
for (let i = 0; i < this.workers.length; i++) {
this.workers[i].removeAllListeners();
this.workers[i].terminate();
}
}
sendMessage(msg) {
if (this.terminating)
return;
this.index++;
const nr = this.index % this.worker;
this.workers[nr].postMessage(msg);
}
postMessage(msg) {
if (this.terminating)
return;
if (this.rateLimit <= 0)
this.sendMessage(msg);
else
this.addToQueue(msg);
}
addToQueue(msg) {
if (this.terminating)
return;
// add new element to queue
const length = this.queue.unshift(msg);
// run timer
this.runTimer();
// remove last element from queue
if (length >= 5)
this.queue.pop();
}
sendFromQueue() {
const msg = this.queue.shift();
this.queue = []; // delete all other messages
if (msg)
this.sendMessage(msg);
}
runTimer(force = false) {
if (!force && this.timer === 'running')
return;
this.timer = 'running';
this.sendFromQueue();
setTimeout(() => {
if (this.queue.length > 0)
this.runTimer(true);
else
this.timer = 'idle';
}, this.rateLimit);
}
create(init = {}) {
if (this.terminating)
return;
const worker = new worker_threads_1.Worker((0, path_1.join)(__dirname, this.script));
// pass init object once worker is online
worker.on('online', () => {
worker.postMessage(JSON.stringify({ init }));
});
worker.on('message', msg => {
this.emit('message', msg);
});
if (this.logLevel >= 2) {
worker.on('error', err => {
console.log('WORKER error:', err);
});
worker.on('exit', err => {
console.log('WORKER exit:', err);
});
worker.on('messageerror', err => {
console.log('WORKER messageerror:', err);
});
}
this.workers.push(worker);
}
}
exports.default = WorkerPool;
//# sourceMappingURL=workerPool.js.map