MWSE/index.js

88 lines
2.4 KiB
JavaScript

/** @type {import('node:cluster').Cluster} */
const cluster = require("cluster");
const os = require("os");
/**
* Use Round Robin algorithm for cluster process load balancer
*/
cluster.schedulingPolicy = cluster.SCHED_RR;
async function main()
{
if(cluster.isPrimary == false)
{
console.log("Slave", process.pid);
// This process is a worker / slave
// Compile source code and run
require("./Source/index");
// stay here
return;
};
// This process is a primary / master
console.log("Master", process.pid);
// Worker process list
const master = new Map();
const coreCount = os.cpus().length;
for(let index = 0; index < coreCount; index++)
{
// Open slave process
let worker = await generateFlow();
// Save process with id
master.set(worker.id, worker);
// Listen process for commands
worker.message(
// This process want to send payload to sibling process with IPC
(workerId, payload) =>{
// Check Target worker
if(payload.process)
{
master.get(payload.process).send({
...payload,
pid: worker.id
})
}else for (const [siblingWorkerId,{send}] of master) {
// No sending to itself
if(workerId !== siblingWorkerId)
{
// Send command to sibling with IPC
send({
...payload,
pid: worker.id
})
}
}
}
)
}
}
async function generateFlow(N)
{
// Mirror this process with for (low-level os multitasking)
const worker = cluster.fork();
// Wait process is online
await new Promise(ok => {
worker.addListener("online",()=> {
ok()
})
});
// Get process pid on the os
let id = worker.process.pid;
// Simplification wrapping send and get events with IPC's event functions
return {
id,
send: message => worker.send(message),
message: (callback) => worker.addListener("message", e => callback(id,e))
}
}
// Run immediately
process.nextTick(main);