I am using the following Code, to perform a cost intensive calculation using multiple Threads in NodeJS:
Worker:
import { workerData, parentPort } from 'worker_threads';
let digits = workerData as number[];
let digitCount = digits.length;
// Worker Code
parentPort.on('message', (msg) => {
let [start, end] = msg;
for(let i = start; i < end; i++) {
let res = calculate(digits, digitCount, msg);
if(res) {
parentPort.postMessage(res);
}
}
parentPort.postMessage(true);
process.exit(0);
});
Main:
import { Worker } from 'worker_threads';
import { cpus } from 'os';
export class WorkerPool {
private workers: Worker[];
private resolve: (value: void | PromiseLike<void>) => void;
private done: number;
constructor(digits: number[], occurances: Map<number, number | false>, private count: number = (cpus().length - 1)) {
if(count < 1) count = 1;
this.workers = new Array<Worker>(count);
for(let i = 0; i < count; i++) {
let worker: Worker = new Worker(require.resolve('./worker'), {
workerData: digits,
}) as Worker;
this.workers[i] = worker;
worker.on('message', (val: number | true) => {
if(val === true) {
if(++this.done >= count) {
this.resolve();
}
return;
}
let idx = occurances.get(val);
if(idx === undefined) {
occurances.set(val, i);
} else if(idx !== false) {
occurances.set(val, false);
}
});
}
}
calculate(maxi: number) {
return new Promise<void>((resolve, reject) => {
this.resolve = resolve;
let d = Math.floor(maxi / this.count);
let r = maxi % this.count;
let start = 0;
for(let i = 0; i < this.count; i++) {
let end = start + d + (i < r ? 1 : 0);
this.workers[i].postMessage([start, end]);
start = end;
}
});
}
}
The function calculate is just a relatively simple function, however it is run around 1 billion times. That is why i tried to use multithreading. However, when i do
await pool.calculate(1000000000)
the calculation does not finish and the Ram usage goes to 64GB. When running the calculate function in the main Thread, it works as expected, so i guess it's a fault in my WorkerPool class.