Amigo, antes de continuar vou te passar a real... Talvez vc não goste, mas o V8 -> Node foi desenhado em uma arquitetura single thread com a premissa de I/O Non Blocking! A mágica do V8 -> Node ser "performatico" e "escalável" em single thread é simplismente pq não existem (pelo menos esse é o conceito, não deve existir) operações de I/O síncronas!
Óbvio, o cara que é estúpido, fai fazer operações I/O síncronas no Node bloqueando sua aplicação inteira e travando tudo!
Simplesmente utilize o Node como ele foi projetado, sem operações que consomen processamento de CPU (Ex, um loop qualquer em servidor NodeJs faz sua aplicação inteira "travar", devido a natureza single thread, esse loop pode ser um código que vc fez mal escrito ou uma operação I/O síncrona). Entretanto, em relação a qualquer operação de I/O assíncrona (objetivo do projeto NodeJs - Arquitetura "Non Blocking" ou Event Driven Architecture) pode ficar super tranquilo que nenhumas delas vão "afetar" sua aplicação.
-
Se seu foco é tentar "aumentar" a escalabilidade de um servidor NodeJs, não recomendo este caminho...
-
Se arquitetura multi threaded é o que vc precisa (existem muitos motivos factuais que justificam isso) sugiro ir para outra tecnologia tipo .NET Core, Java, Golang, ....
- Se n tem jeito, tem que ficar no Node, usa essa lib: https://www.npmjs.com/package/piscina
Ciente disso, acho o experimento bacana e parabéns pela iniciativa! Olhando o seu código por cima, acredito que tem uma falha na arquitetura. JobsQueue só é consumido qud um worker dispara uma mesnagem do tipo response. Ou seja, a relação de produtor <-> consumidor do JobsQueue está 'serializada' indiretamente. Vc precisa de um "loop" 'assíncrono' para disparar o consumo do JobsQueue: Ex:
setInterval(() => {
let firstValue = JobsQueue.values().next().value;
if (firstValue) {
threadPool.set(message.workerId, {
working: true,
socketId: firstValue.socketId,
worker: worker,
});
worker.postMessage({
action: "handle",
path: firstValue.path,
workerId: message.workerId,
socketId: firstValue.socketId,
});
JobsQueue.delete(firstValue);
}
}, 1000); // interval para exemplo hipotético
Esse não é o código ideal para essa arquitetura, é um armengue para simular um consumidor assíncrono do JobsQueue. Mas acho que resolve seu problema.
Parece que este tutorial está implementando isto com a arquitetura adequada, seguindo as recomendações do Node: https://www.digitalocean.com/community/tutorials/how-to-use-multithreading-in-node-js, usa isto como base para seu estudo.