rfidnatura/worker/workerPool.js

77 lines
2.2 KiB
JavaScript

const { Worker } = require('worker_threads');
const log4js = require('log4js');
// Configuración de log4js
log4js.configure({
appenders: {
out: { type: 'stdout' },
app: { type: 'file', filename: 'app.log' }
},
categories: { default: { appenders: ['out', 'app'], level: 'debug' } }
});
const logger = log4js.getLogger();
// Clase para gestionar workers
class WorkerPool {
constructor(numWorkers) {
this.numWorkers = numWorkers;
this.workers = [];
this.initWorkers();
}
// Inicializar workers
initWorkers() {
for (let i = 0; i < this.numWorkers; 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'); // Pedir al worker que verifique nuevos registros
});
worker.on('error', error => {
logger.error('Error en el worker:', error);
// Si un worker falla, lo eliminamos del array y creamos uno nuevo
this.replaceWorker(worker);
});
worker.on('exit', code => {
if (code !== 0) {
logger.error(`Worker stopped with exit code ${code}`);
this.replaceWorker(worker);
}
});
this.workers.push(worker);
}
// Reemplazar un worker fallido
replaceWorker(failedWorker) {
this.workers = this.workers.filter(worker => worker !== failedWorker);
this.createWorker();
}
// Asignar tareas iniciales a los workers
async start() {
const decoration = '△▽'.repeat(10);
console.log(`${decoration} Dismuntel service ${decoration}`);
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();
console.log('\nBye ( ◕ ‿ ◕ )っ');
} catch (err) {
console.error(err);
}
process.exit();
}
}
module.exports = WorkerPool;