From 36ecb5c6a71908376bf2eb33074cc3201a1a81c4 Mon Sep 17 00:00:00 2001 From: BurnyLlama Date: Wed, 13 Oct 2021 19:45:59 +0200 Subject: [PATCH] Working multithreading... --- libs/utils/multithread.js | 35 ++++++++++--------- libs/utils/multithread/fibonacci.js | 46 ++++++++++++++----------- libs/utils/multithread/genericWorker.js | 27 +++++++++------ tests/multihread.test.js | 20 ++++++++++- 4 files changed, 80 insertions(+), 48 deletions(-) diff --git a/libs/utils/multithread.js b/libs/utils/multithread.js index 56128b4..f64b369 100644 --- a/libs/utils/multithread.js +++ b/libs/utils/multithread.js @@ -10,27 +10,28 @@ export function initWorkers(threads) { for (const i in workerFarm) { const worker = workerFarm[i] worker.postMessage({ - type: 'setName', + type: 'initWorker', name: `Worker ${parseInt(i) + 1}` }) } } -export function spread(threads, script, data, shouldEval) { - return new Promise((resolve, reject) => { - const worker = new Worker( - script, - { - workerData: data, - eval: shouldEval ?? false - } - ) +let spreadIndex = 0 +export function spread(script, data) { + return new Promise( + (resolve, reject) => { + const worker = workerFarm[spreadIndex] + worker.postMessage({ + type: 'runScript', + script, + data + }) - worker.on('message', resolve) - worker.on('error', reject) - worker.on('exit', (code) => { - if (code !== 0) - reject(new Error(`Process stopped with code: ${code}`)) - }) - }) + worker.once('message', result => resolve(result)) + + ++spreadIndex + if(spreadIndex >= workerFarm.length) + spreadIndex = 0 + } + ) } \ No newline at end of file diff --git a/libs/utils/multithread/fibonacci.js b/libs/utils/multithread/fibonacci.js index c577302..bf93a79 100644 --- a/libs/utils/multithread/fibonacci.js +++ b/libs/utils/multithread/fibonacci.js @@ -1,23 +1,29 @@ -import { workerData, parentPort } from 'worker_threads' +import initLog from '../log.js' -let nums = [1, 1] +const log = initLog('Fibonacci') -for (let i = 0; i < 42; i++) { - nums.push(nums[nums.length - 2] + nums[nums.length - 1]) -} +export function main(data) { + return new Promise( + (resolve, reject) => { + let nums = [1, 1] + + for (let i = 0; i < 44; i++) { + nums.push(nums[nums.length - 2] + nums[nums.length - 1]) + } + + let primes = [] + for (const num of nums) { + let isPrime = true + for (let i = 2; i < num / 2; ++i) { + if (num % i === 0) + isPrime = false + } + + if (isPrime) + primes.push(num) + } -let primes = [] -for (const num of nums) { - let isPrime = true - for (let i = 2; i < num / 2; ++i) { - if (num % i === 0) - isPrime = false - } - - if (isPrime) - primes.push(num) -} - -console.log("DONE!") - -parentPort.postMessage(primes) \ No newline at end of file + resolve(primes) + } + ) +} \ No newline at end of file diff --git a/libs/utils/multithread/genericWorker.js b/libs/utils/multithread/genericWorker.js index 73a4ff4..e146719 100644 --- a/libs/utils/multithread/genericWorker.js +++ b/libs/utils/multithread/genericWorker.js @@ -1,30 +1,37 @@ import { workerData, parentPort } from 'worker_threads' import initLog from '../log.js' -let script = '' +let runScript = '' let myName = '' let log = initLog(myName) parentPort.on( 'message', - message => { + async message => { switch (message.type) { - case 'setName': + case 'initWorker': myName = message.name log = initLog(myName) - log(`Changed name to '${myName}'.`) + process.env.DEBUG && log(`Started new thread -> «${myName}»`) break - case 'setScript': - script = message.script - log = initLog(myName) - log(`Changed name to '${myName}'.`) + case 'runScript': + runScript = message.script + process.env.DEBUG && log(`Running script -> «${runScript}»`) + + import(runScript).then( + script => script.main(message.data).then( + result => { + parentPort.postMessage(result) + process.env.DEBUG && log(`Script done -> «${runScript}»`) + } + ) + ) break - default: - + log(`Invalid message -> ${message.type ?? 'No message type provided!'}`) break } } diff --git a/tests/multihread.test.js b/tests/multihread.test.js index 71c2f1d..4a192b9 100644 --- a/tests/multihread.test.js +++ b/tests/multihread.test.js @@ -1,3 +1,21 @@ import { initWorkers, spread } from '../libs/utils/multithread.js' -initWorkers(8) \ No newline at end of file +initWorkers(10) + +let processes = 20 +let ran = 0 +for (let i = 0; i < processes; ++i) { + spread( + './fibonacci.js', + {} + ).then( + result => { + console.log(i) + + ++ran + if (ran === processes) { + process.exit(0) + } + } + ) +} \ No newline at end of file