module.exports = () => { const workers = {}; const runningJobs = {}; let jobQueue = []; const dequeue = () => { if (jobQueue.length !== 0) { const wIds = Object.keys(workers); for (let i = 0; i < wIds.length; i += 1) { if (typeof runningJobs[wIds[i]] === 'undefined') { jobQueue[0](workers[wIds[i]]); break; } } } }; const queue = job => ( new Promise((resolve, reject) => { jobQueue.push((w) => { const { action } = job; jobQueue.shift(); w.setResolve(action, (data) => { delete runningJobs[w.id]; dequeue(); resolve(data); }); w.setReject(action, reject); runningJobs[w.id] = job; job.start(w); }); dequeue(); }) ); const addWorker = (w) => { workers[w.id] = w; return w.id; }; const addJob = job => ( queue(job) ); const terminate = () => { Object.keys(workers).forEach((id) => { workers[id].terminate(); }); jobQueue = []; }; return { addWorker, addJob, terminate, }; };