Vscode: Node.js Cluster Example Fails under VS Code

Created on 20 Feb 2016  Â·  32Comments  Â·  Source: microsoft/vscode

Environment:

  • VS Code Version 0.10.9
  • Mac OS 10.10.5
  • Node.js v4.3.1

Steps to Reproduce:
Create a new directory named cluster-test
Create a new file cluster-test\app.js with sample code from https://nodejs.org/dist/latest-v4.x/docs/api/cluster.html#cluster_cluster as follows:

const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
  // Fork workers.
  for (var i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

  cluster.on('exit', (worker, code, signal) => {
    console.log(`worker ${worker.process.pid} died`);
  });
} else {
  // Workers can share any TCP connection
  // In this case it is an HTTP server
  http.createServer((req, res) => {
    res.writeHead(200);
    res.end('hello world\n');
  }).listen(8000);
}

Open cluster-test in VS Code
Switch to the Debug view and click the Start icon, or press F5
Select "Node.js" as the debug environment
Click Start again

Point you browser to http://localhost:8000/
Observe that no one is listening

Exit VS code, open a command prompt and invoke:
node cluster-test\app.js

Point you browser to http://localhost:8000/
Observe that a "hello world" response is received

Conclusion:
Basic node cluster example fails in VS Code

*duplicate debug feature-request

Most helpful comment

The 2nd workaround is the preferred way if you actually want to debug any worker and not just the first process that is launched.

what could be the workaround if I want to debug all workers in the same time ?

All 32 comments

@curtw how does you launch config look like?

My launch.json file is unaltered from that which VS Code created by default:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Launch",
            "type": "node",
            "request": "launch",
            "program": "${workspaceRoot}/app.js",
            "stopOnEntry": false,
            "args": [],
            "cwd": "${workspaceRoot}",
            "runtimeExecutable": null,
            "runtimeArgs": [
                "--nolazy"
            ],
            "env": {
                "NODE_ENV": "development"
            },
            "externalConsole": false,
            "sourceMaps": false,
            "outDir": null
        },
        {
            "name": "Attach",
            "type": "node",
            "request": "attach",
            "port": 5858,
            "sourceMaps": false,
            "outDir": null,
            "localRoot": "${workspaceRoot}",
            "remoteRoot": null
        }
    ]
}

Reproduced for me in debug mode
But this example works when launching without debugging (ctrl + F5\ cmd + F5)

vscode default use --debug-brk to enable the debug support which block the child process at beginning.

+1
In my case, not works when using sticky-cluster module, but using ctrl+F5 normally works ..T_T

Yes, the --debug-brk option is the problem. Currently there is no way to prevent VS Code from using this option, but there are two workarounds:

  1. change the argument by adding this statement as the first line to app.js:

process.execArgv[0] = process.execArgv[0].replace('-brk', '');

  1. or launch node from a terminal and attach to it with the VS Code debugger.

Run in terminal:

node --debug app.js

Then select the default 'attach' launch config and attach to it.

The 2nd workaround is the preferred way if you actually want to debug any worker and not just the first process that is launched.
For the example from above you could add the debug port to the hello world message:

res.end(`hello world ${process.debugPort}\n`);

and then you can attach to that port with VS Code.

BTW, in the latest VS Code Insider you can use the new process picker support to select the cluster worker that you want to debug. After starting the cluster app from a terminal:

node app.js

run the 'Attach to Process' launch config and select a process:

2016-06-10_12-42-43

The 2nd workaround is the preferred way if you actually want to debug any worker and not just the first process that is launched.

what could be the workaround if I want to debug all workers in the same time ?

@weinand When I launch a node js process that is clustered, and try to 'Attach to Process', I only have the master process in the list. How do you manage to have the master process, and all the forks in your list (your screenshot) ?

I was facing the same issue in my web app, what I did is the following:

if (cluster.isMaster && process.env.NODE_ENV !== "development")
app.listen(port, function () {
    if(cluster.worker)
        console.log("Worker %d running! App listening on port %s", cluster.worker.id, port);
    else
        console.log("App listening on port %s", port);
});

Because I only need this feature in production. 😄

Cheers sant123 thats good enough for me to investigate if vscode is good to test with :)

FYI, starting with the October release VS Code supports multi session debugging. This means you can create multiple launch configurations that attach to different debug ports. But you would have to trigger these launch configs manually...

A better way could be to write a small extension that uses a launch config as a template and starts multiple debug sessions out of it (and varies the debug port for each of them).

Or this extension could use the 'process picker' code from here to find the process IDs of all node processes and then create debug sessions that attach to those processes.

you cannot use hack :

process.execArgv[0] = process.execArgv[0].replace('-brk', '');

with "type": "node2",

Any updates on this issue @weinand ?

Something you can try is pm2. From here I just forget the need to create clusters in my code, because this creates them for me. This is useful for development and production environments. At the end, you write your code as a single process but you can turn it to multiple process.

we had write inspector-proxy to proxy the workers debugPort, so in VSCode we just need to attach to one port without worry abut increate debugPort.

@sant123 We do use pm2 too, however that doesn't help you if one of your instances is launching a background task which is running as it's own process. That still doesn't allow you to debug the launched process with the VScode debugger.

Why can't VS Code have the option to detect when a cluster.fork happens, then automatically connect to that process and start a debug session? That seems like it would be the Right Thing To Do because you'd be debugging all child processes and it would just hit all the breakpoints no matter which process hit them.

Other IDEs like Webstorm have indeed better support for debugging child processes. I hope the VSCode team is going to work on a better support too.

Any suggestions how to detect the cluster.fork?
We do accept pull requests!

seems WebStorm will monitor the main process's child process tree, and auto attach them

when debug with:

    {
      "type": "node",
      "request": "launch",
      "name": "Egg Debug",
      "runtimeExecutable": "npm",
      "runtimeArgs": [
        "run",
        "debug","--", "--workers=2"
      ],
      "console": "integratedTerminal",
      "restart": true,
      "protocol": "auto",
      "port": 9999
    }

the process tree is:

➜  showcase git:(master) ✗ pstree -s showcase
-+= 00001 root /sbin/launchd
 \-+= 00806 tz /Applications/Visual Studio Code.app/Contents/MacOS/Electron -psn_0_122910
   \-+- 01821 tz /Applications/Visual Studio Code.app/Contents/Frameworks/Code Helper.app/Contents/MacOS/Code Helper --type=renderer --js-flags=--nolazy --no-sandbox --primordial-pipe-token=835C6
     \-+- 02161 tz /Applications/Visual Studio Code.app/Contents/Frameworks/Code Helper.app/Contents/MacOS/Code Helper /Applications/Visual Studio Code.app/Contents/Resources/app/out/bootstrap --
       \-+= 02162 tz /bin/zsh -l
         \-+= 02258 tz npm
           \-+- 02261 tz node /Users/tz/Workspaces/eggjs/test/showcase/node_modules/.bin/egg-bin debug --workers=2
             \-+- 02269 tz /Users/tz/git/nvs/node/8.9.0/x64/bin/node --inspect /Users/tz/Workspaces/eggjs/test/showcase/node_modules/[email protected]@egg-bin/lib/start-cluster {"workers":1,"baseDir
               |--- 02273 tz /Users/tz/git/nvs/node/8.9.0/x64/bin/node --inspect --debug-port=5800 /Users/tz/Workspaces/eggjs/test/showcase/node_modules/[email protected]@egg-cluster/lib/agent_
               \--- 02274 tz /Users/tz/git/nvs/node/8.9.0/x64/bin/node --inspect --inspect-port=9230 /Users/tz/Workspaces/eggjs/test/showcase/node_modules/[email protected]@egg-cluster/lib/app_

so I guess WebStorm will do this:

  • find the main program pid 02258 tz npm
  • monitor the child tree of this pid
  • if the child / grandson process had debug execArgv, then attach it

Oh this looks like a perfect opportunity for an extension!

yes, @weinand, I had try before, but got some problem:

I don't know how to got the main process pid which vscode debugger started (02258 tz npm), onDidStartDebugSession don't return the pid.

The Node community is currently working on a PR that will add support of debugging fork/child processes via the new Inspector Protocol target domain. We should strive to add support for new sub targets via this API, and are already tracing the work in our core library: https://github.com/Microsoft/vscode-chrome-debug-core/issues/251

This issue has been closed because it is not within the scope of the core product, but could be addressed by an extension. The VS Code Marketplace shows all existing extensions and you can get started writing your own extension in a few simple steps. See also our issue reporting guidelines.

Happy Coding!

@isidorn Huh? Why is this an extension candidate? Automatically attaching to the correct port for cluster child processes seems well within the remit of VS Code considering it comes with a debugger and multi-process debugging.

The extension candidate label was already present in this issue, I simply reapplied it.
I see the discussion seems lively so I can reopen the issue and @weinand can decide on how to proceed

@weinand Any update? What's the plan for this?

For another project I wrote an extension that tracks all child processes of VS Code (which could include a node.js cluster) and allows to pick node.js processes for debugging based on ports or pids.
This could be an alternative way of supporting a node.js cluster (alternative to the new Inspector Protocol target domain mentioned above).

I followed my own suggestion: please see some progress in https://github.com/Microsoft/vscode/issues/40123

duplicate of #40123.

Was this page helpful?
0 / 5 - 0 ratings