Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I create a direct communication channel between two worker threads in Node.js

Is there a way to create a direct communication channel using new MessageChannel between two worker threads? For Eg: There is a main thread P that I have created using the worker_thread API, which creates two worker threads W1 and W2

P -> W1
  -> W2

I want to enable communication between W1 and W2 directly instead of going via P using parentPort.

like image 978
tusharmath Avatar asked Sep 12 '19 02:09

tusharmath


People also ask

What is the difference between cluster and worker_threads packages in node JS?

Clusters of Node. js processes can be used to run multiple instances of Node. js that can distribute workloads among their application threads. When process isolation is not needed, use the worker_threads module instead, which allows running multiple application threads within a single Node.

How does node js handle child threads?

Node. js is a single-threaded language and uses the multiple threads in the background for certain tasks as I/O calls but it does not expose child threads to the developer. But node. js gives us ways to work around if we really need to do some work parallelly to our main single thread process.


1 Answers

Use new MessageChannel() to generate a two-way communications channel.

index.js

const { Worker } = require('worker_threads');

const path = require('path'); 

const w1 = new Worker(path.join(__dirname,'./worker1.js'));
const w2 = new Worker(path.join(__dirname,'./worker2.js'));

w1.once('message', value => {
    w2.postMessage({
        port: value.port
    }, [value.port]);
});

w2.once('message', value => {
    w1.postMessage({
        port: value.port
    }, [value.port]);
});

worker1.js

const { MessageChannel, parentPort,  } = require('worker_threads');

let woker2Port;
console.log('worker1 started');

const { port1, port2 } = new MessageChannel();
port1.on('message', (value) => {
    console.log(value);
});

parentPort.postMessage({
    port: port2,
}, [port2]);

parentPort.on('message', value => {
    if (value.port) {
        woker2Port = value.port;
        woker2Port.postMessage({msg:'i am worker1!'});// send msg to worker2
        return;
    }
});

worker2.js

const { MessageChannel, parentPort,  } = require('worker_threads');

let woker1Port;
console.log('worker2 started');

const { port1, port2 } = new MessageChannel();
port1.on('message', (value) => {
    console.log(value);
});

parentPort.postMessage({
    port: port2,
}, [port2]);

parentPort.on('message', value => {
    if (value.port) {
        woker1Port = value.port;
        woker1Port.postMessage({msg:'i am worker2!'});// send msg to worker1
    }
});

Notice: if you debug this code in VSCode, you won't see the log print in worker1.js and worker2.js. Run node index directly or debug it in ndb works fine!

like image 68
lx1412 Avatar answered Oct 01 '22 15:10

lx1412