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

cluster: worker doesn't react on message #39854

Closed
relloccate opened this issue Aug 23, 2021 · 7 comments
Closed

cluster: worker doesn't react on message #39854

relloccate opened this issue Aug 23, 2021 · 7 comments
Labels
cluster Issues and PRs related to the cluster subsystem. esm Issues and PRs related to the ECMAScript Modules implementation.

Comments

@relloccate
Copy link

relloccate commented Aug 23, 2021

Hi there.

I have a problem:
The Worker doesn't react on "message" event from the Primary with: type: "module" enabled in package.json
But the Primary is react on "message" event from the worker

Without type: "module" both works.

win10 x64 (node v14.17.5 and v16.7.0)
Guys, any fixes? Thanks.

Example:

import cluster from 'cluster';

if (cluster.isMaster) {
    const worker = cluster.fork();

    worker.on('message', message => {
        // will log the message
        console.log(message);
    });

    worker.send('From Master');
} else {
    process.on('message', message => {
        // will not log the message
        console.log(message);
    });

    process.send('From Worker');
}

Doesn't work ONLY with enabled node.js imports.

@PurnashisHazra
Copy link

Could you create a repo which replicates this problem? Can I take this issue up?

@relloccate
Copy link
Author

relloccate commented Aug 23, 2021

Could you create a repo which replicates this problem? Can I take this issue up?

The example above, just a minimal and illustrative example. Pretty simple to test on your PC. Sorry, I did not understand why you need a repo.

@PurnashisHazra
Copy link

Just with some tests and all for easy debugging . Nevermind, I'll take up this issue

@Ayase-252 Ayase-252 added cluster Issues and PRs related to the cluster subsystem. esm Issues and PRs related to the ECMAScript Modules implementation. labels Aug 24, 2021
@Linkgoron
Copy link
Member

Linkgoron commented Aug 27, 2021

This is probably a duplicate of #37782 and #39140

e.g. this works:

import cluster from 'cluster';

if (cluster.isMaster) {
    const worker = cluster.fork();
    worker.on('message', message => {
        console.log(message);
    });
    setTimeout(() => {
        worker.send('From Master');
    }, 1000);
} else {
    process.on('message', message => {
        console.log(message);
    });

    process.send('From Worker');
}

tl;dr of the other issues, there's a minor race condition (read: bug) because modules are now loaded asynchronously and when starting a module messages are missed as you don't register in time to get them. The safest way to start without a race condition is to get a ping from the child and then you know you're safe. e.g. POC:

import cluster from 'cluster';
import { once } from 'events';

if (cluster.isMaster) {
    const worker = cluster.fork();

    let firstMessage = true
    worker.on('message', message => {
        if (firstMessage) {
            firstMessage = false;
        } else {
            console.log(message);
        }
    });
    await once(worker, 'message');
    worker.send('From Master');
} else {
    process.on('message', message => {
        console.log(message);
    });

    process.send('IM READY');
    process.send('From Worker');
}

@relloccate
Copy link
Author

relloccate commented Aug 27, 2021

Yes, i saw #37782 after.
"modules are now loaded asynchronously" - With babel or no ESM it works correctly without any timeouts.
Anyway thank you, i did it and it worked.

My Solution:

import cluster from 'cluster';

if (cluster.isMaster) {
    const worker = cluster.fork();

    worker.on('message', message => {
        if (message === 'getPayload') {
            worker.send({ payload: 'something' });
        }
    });
} else {
    process.on('message', ({ payload }) => {
        console.log(payload);
    });

    process.send('getPayload');
}

@relloccate
Copy link
Author

Dupe of #37782

@Linkgoron
Copy link
Member

Yes, i saw #37782 after.
"modules are now loaded asynchronously" - With babel or no ESM it works correctly without any timeouts.

Just to clarify - when I said modules what I meant was that ESM modules (as in type: module or .mjs) are loaded asynchronously (e.g. for top-level await etc), while using CommonJS is still synchronous - not that all code is now loaded asynchronously.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cluster Issues and PRs related to the cluster subsystem. esm Issues and PRs related to the ECMAScript Modules implementation.
Projects
None yet
Development

No branches or pull requests

4 participants