UNPKG

node-ebook-converter

Version:

Node.js minimal and powerful ebook converter (single package) with built-in queue and threading functionalities

50 lines (39 loc) 1.65 kB
const { Worker, isMainThread, MessageChannel } = require('worker_threads'); const path = require('path'); /* Pool related variables. poolSize defines simultaneous processing limit, executionQueue stores running workers, and idleQueue stores idle workers. */ let poolSize = 1; let executionQueue = []; let idleQueue = []; function convert (data) { if (!isMainThread) return; const removeWorkerFromQueue = (id) => { executionQueue = executionQueue.filter(item => item.worker.threadId !== id); refreshExecutionQueue(); } const addWorkerToQueue = (item) => { idleQueue.push(item); refreshExecutionQueue(); } const refreshExecutionQueue = () => { if (executionQueue.length >= poolSize || idleQueue.length === 0) return; const item = idleQueue[0]; executionQueue.push(item); item.worker.postMessage({ port: item.port }, [item.port]); idleQueue.shift(); } return new Promise((resolve, reject) => { data.input = path.resolve(require.main.path, data.input); data.output = path.resolve(require.main.path, data.output); const worker = new Worker(path.join(__dirname, './src/converter.js'), { env: { ...data } }); const channel = new MessageChannel(); channel.port2.on('message', value => resolve(value)); channel.port2.on('close', () => removeWorkerFromQueue(worker.threadId)); worker.on('error', error => reject(error)); addWorkerToQueue({ ...data, worker, port: channel.port1 }); }); } exports.convert = convert; exports.setPoolSize = (value) => { poolSize = value };