Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

listen() dosen't work with cluster on "node -e" #14168

Closed
FCO opened this issue Mar 26, 2015 · 4 comments
Closed

listen() dosen't work with cluster on "node -e" #14168

FCO opened this issue Mar 26, 2015 · 4 comments

Comments

@FCO
Copy link

FCO commented Mar 26, 2015

on node v0.12.0

Show my simple test module using cluster

(master) [fcorrea@dev04c6 ~/olx_push_service]$ cat use_cluster.js 
var cluster = require('cluster');
var http = require('http');
var numCPUs = require('os').cpus().length;

function CallCluster(cb) {
    this.server = http.createServer(function(req, res) {
        res.writeHead(200);
        res.end("hello world\n");
    });
}
CallCluster.prototype.listen = function(port, cb) {
    console.log("running...");
    if (cluster.isMaster) {
        cluster.fork();
        cluster.on('listening', function(){console.log("listening...")});
        cluster.on('exit', function(worker, code, signal) {
            console.log('worker ' + worker.process.pid + ' died');
        });
    } else {
        this.server.listen(port);
        setImmediate(cb.bind(http));
    }
};

module.exports = CallCluster;

A simple script to call the module

(master) [fcorrea@dev04c6 ~/olx_push_service]$ cat call_call_cluster.js 
var CallCluster = require("./use_cluster.js");

var cc = new CallCluster();

cc.listen(9999, function(){console.log("listening")});

Running that file, everything works, the listen() calls its callback and the script keeps running.

(master) [fcorrea@dev04c6 ~/olx_push_service]$ node call_call_cluster.js 
running...
running...
listening
listening...
^C

Running the same script by "node -e" does't call the listen() callback, the worker dies and the script stops running

(master) [fcorrea@dev04c6 ~/olx_push_service]$ node -e '                       
var CallCluster = require("./use_cluster.js");

var cc = new CallCluster();

cc.listen(9999, function(){console.log("listening")});

'
running...
running...
listening
worker 16384 died
(master) [fcorrea@dev04c6 ~/olx_push_service]$

Is that a bug? Why isn't that working?

@misterdjules
Copy link

Thank you for reporting this issue!

It's a bug in the sense that using node -e doesn't setup what's necessary for workers to be functional.

I don't know if that's intentional. I don't see any strong reason why one couldn't use the cluster module with node -e, but I can understand why it's not a very common use case. @sam-github @cjihrig What do you think?

The sample code you used to reproduce the problem has another issue: it basically executes call_call_cluster.js twice, as a child process created by child_process.fork doesn't resume its execution from where fork was called, but spawns a new node process that runs the same file that was passed on the command line to run the original program.

This bug can be reproduced with the example provided in the cluster's API documentation.

Thank you again!

@FCO
Copy link
Author

FCO commented Mar 27, 2015

I had another problem with the "-e" flag:
using the -e flag (without cluster) the listen()'s callback isn't called until the first request.

calling the code by a file, the listen()'s callback is called "immediately"

(master) [fcorrea@dev04c6 ~/olx_rest]$ cat test2-e.js 
    require("http").createServer(function(req, res) {
        res.writeHead(200);
        res.end("hello world\n");
    }).listen(9999, function(){console.log("bla")});
(master) [fcorrea@dev04c6 ~/olx_rest]$ node test2-e.js 
bla
^C

When I run the same code with "node -e" the callback waits until the first http request to run

(master) [fcorrea@dev04c6 ~/olx_rest]$ node -e '
    require("http").createServer(function(req, res) {
        res.writeHead(200);
        res.end("hello world\n");
    }).listen(9999, function(){console.log("bla")});
'
^C
(master) [fcorrea@dev04c6 ~/olx_rest]$
(master) [fcorrea@dev04c6 ~/olx_rest]$ node -e '

    require("http").createServer(function(req, res) {
        res.writeHead(200);
        res.end("hello world\n");
    }).listen(9999, function(){console.log("bla")});
' &
[1] 27557
(master) [fcorrea@dev04c6 ~/olx_rest]$ curl 127.0.0.1:9999
bla
hello world
(master) [fcorrea@dev04c6 ~/olx_rest]$

@cjihrig
Copy link

cjihrig commented Mar 27, 2015

I don't really see a use case for using the cluster module with -e. When you call cluster.fork(), there isn't going to be a module to pass to child_process.fork() (cluster forks based on the process settings, not on the module it was called from). IMO, this isn't really the ideal use case for cluster. Using child_process directly would probably be better.

EDIT: By not ideal use case, I was referring to the -e. I am in favor of changing the function signature of cluster.fork() to allow more fine grain control.

EDIT2: If you have your heart set on using this approach, this hack appears to work. Add the following two lines immediately before your call to cluster.fork():

cluster.settings.exec = __filename;
cluster.settings.execArgv = [];

@sam-github
Copy link

You can't call cluster.fork() from the node REPL, either. Use cluster.setupMaster() if you aren't running a file.

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

No branches or pull requests

5 participants