rfidnatura/worker/workerPool.js

73 lines
1.9 KiB
JavaScript

const { Worker } = require('worker_threads');
const chalk = require('chalk');
const log = require('../log')
const env = require('dotenv').config().parsed || process.env;
// Clase para gestionar workers
class WorkerPool {
constructor(numWorkers) {
this.workers = [];
this.initWorkers(numWorkers);
}
// Inicializar workers
initWorkers(number) {
for (let i = 0; i < number; i++) this.createWorker();
}
// Crear un nuevo worker y manejar sus mensajes
createWorker() {
const worker = new Worker('./worker/worker.js');
worker.on('message', async msg => {
if (msg === 'done' || msg === 'error')
worker.postMessage('check');
});
worker.on('error', error => {
log('error', 'Error en el worker:', error);
this.replaceWorker(worker);
});
worker.on('exit', code => {
if (code !== 0) {
log('error', `Worker stopped with exit code ${code}`);
setTimeout(() => {
this.replaceWorker(worker);
}, 1000);
} else {
this.workers = this.workers.filter(worker => worker !== worker);
}
});
this.workers.push(worker);
}
// Reemplazar un worker fallido
replaceWorker(failedWorker) {
this.workers = this.workers.filter(worker => worker !== failedWorker);
log('debug', 'Replacing a worker...');
this.createWorker();
}
// Asignar tareas iniciales a los workers
async start() {
const decoration = '△▽'.repeat(10);
const rfidnatura = chalk.white.bold('Rfid') + chalk.green.bold('Natura')
log(null, `${decoration} ${rfidnatura} ${decoration}`);
if (env.DRY_PRINT)
log('info', 'Dry print mode')
for (const worker of this.workers)
worker.postMessage('check'); // Pedir al worker que verifique nuevos registros
}
// Cerrar todos los workers
end() {
try {
for (const worker of this.workers) worker.terminate();
log(null, '\nBye ( ◕ ‿ ◕ )っ')
} catch (err) {
log('error', err)
}
process.exit();
}
}
module.exports = WorkerPool;