Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MessageChannel messages don't work in both directions #138

Closed
NickHeiner opened this issue Jul 19, 2021 · 3 comments
Closed

MessageChannel messages don't work in both directions #138

NickHeiner opened this issue Jul 19, 2021 · 3 comments

Comments

@NickHeiner
Copy link

When I use worker_threads directly, I'm able to set up a bidirectional communication between the parent and workers:

// parent.js
const { MessageChannel, Worker } = require('worker_threads');
const subChannel = new MessageChannel();

subChannel.port2.on('message', (val) => {
  console.log('parent got message', val)
  subChannel.port2.postMessage('response from parent to ' + val);
});

const worker = new Worker(require.resolve('./message-channel-demo-worker'));
worker.postMessage({ hereIsYourPort: subChannel.port1 }, [subChannel.port1]);
// message-channel-demo-worker.js
const {
  MessagePort, parentPort
} = require('worker_threads');

parentPort.once('message', (value) => {
  value.hereIsYourPort.postMessage('the worker is sending this');

  value.hereIsYourPort.once('message', (val) => console.log('worker got message', val));
});

On Node 14, this produces:

parent got message the worker is sending this
worker got message response from parent to the worker is sending this

However, when I introduce Piscina, the worker thread never gets the message from parent:

// parent-piscina.js
const Piscina = require('piscina');
const { MessageChannel } = require('worker_threads');

const piscina = new Piscina({
  filename: require.resolve('./piscina-message-demo-worker'),
});

const channel = new MessageChannel();

channel.port2.on('message', (message) => {
  console.log('parent got:', message);

  channel.port2.postMessage('response from parent');
});

piscina.runTask({ port: channel.port1 }, [channel.port1]);
// piscina-message-demo-worker.js
module.exports = ({ port }) => {
  port.once('message', (val) => console.log('worker got', val));

  port.postMessage('hello from the worker pool');
};

On Node 14, this hangs at:

parent got: hello from the worker pool

Am I doing this wrong?

Possibly related: #133

@jasnell
Copy link
Collaborator

jasnell commented Jul 19, 2021

Hmm... will have to investigate. @addaleax, any ideas?

@tuanzisama
Copy link

I got a same problem.
When i try to find answer, put a useless code console.log(123); in worker.js. It's work!
I still don't know how this works.

Example:

// piscina-message-demo-worker.js
module.exports = ({ port }) => {
  // put a useless console.
  console.log(123);

  port.once('message', (val) => console.log('worker got', val));
  port.postMessage('hello from the worker pool');
};

@addaleax
Copy link
Collaborator

addaleax commented Oct 4, 2021

You’ll want useAtomics: false if you plan to communicate with the worker thread externally, instead of using piscina’s built-in communication mechanism.

It’s going to be a bit slower in that case, but that’s probably fine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants