-
Notifications
You must be signed in to change notification settings - Fork 78
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
proposal: --inspect-store flag #298
Comments
So … my first intuitive preference would be to “let userland handle this” – it’s not too complicated to set |
I feel bit queasy about accessing the filesystem on Node.js startup - so much can go wrong. No access to a writable FS might also be a common problem...
Command line flag also requires controlling the process.
Is anything other then URL (or even port) required? Given the port one can always access the /json/list endpoint for that process.
Would it be possible to solve this by having "parent" instance in fork and cluster scenarios cover this role? Then parent instances could publish child instances in their One problem I see is if the "hierarchy chain" is broken on some level because some process terminated. |
I have experience using this approach inside ndb and it comes with following disadvantages:
|
I am writing tool so I should create something writable before passing it to node. If node can not write to file then it won't and tool won't detect processes and should fix it on its side. We already have some flags that dumps information to file e.g.
Only url with port are required but I believe that if we are dumping something - it is nice to dump something already available to not create new format for almost the same information.
In general if we run anything - it means that we run something differently in comparison with normal run and most implementations should be as simple as possible to avoid pollution of inspecting process so they should get url as fast as possible and dump it using as less code as possible. As soon as you get more complicated logic there user will be closer and closer to a point when they inspect/debug this code than actual node scripts.
It can be worse, inspected processes might not know about each other, imagine that there are multiple processes running on cron and you'd like to build a tool for them. With my solution you create folder, setup |
Not sure I follow this part. Wouldn't writing to a file, picking up the change, and then trying to connect also realistically miss the startup of node? |
If in addition to So writing files and waiting for |
The file specified by What is the use case of this flag? Is the consumer looking for the endpoint given a PID, or is it trying to find all Node.js process with such endpoints open and these endpoints? |
It looks like we use a lot of files in Node, I definitely can follow all best practice in this area. Thanks for these examples.
Consumer is trying to find all Node.js processes started inside current process environment with such endpoints. Process environment has nice property that it is inherited by default by child processes. There are two use cases:
|
Can there be just a single file that gets appended? |
In theory yes but in this case different node processes will need to implement some kind of synchronization between them to not messed up each other additions. If node has native support for some file based database - it can be used here, but I believe that all file based databases are implemented in user land. |
Thanks for the explanation.
As I understand, the consumer does not need to discover and attach to child processes after they are already started? I wonder whether we could do the reverse: instead of having the consumer reading something from a folder, we actively notify the consumer from the Node.js instances - e.g. through a pipe or a domain socket, i.e. something like our |
I do not want to limit consumer in this way. If consumer would like to have, scheduled using cron, script that starts from time to time, detect all running node instances and captures sampling heap profile using protocol to aggregate this data later - it sounds like pretty valid use case. With proposed solution consumer needs to pass
Reverse connection might give us a lot of more flexibility over how information about discovered node processes is stored. I like it but at the same time it adds requirement for some demon that is running in background and requires some cpu cycles. I actually tried reverse connection with |
I was thinking about current available capabilities a little bit more and I can say that parsing
|
I see, that's fair.
What happens if
I think there are some trade-offs here. Using the file system means we are adding another layer of states to manage, which may be out of sync with the actual states in the processes (since we are not managing those in-memory). For instance, what if the process crashes without having a chance to clean up the file? |
Good point. If it is possible then it would be nice to prohibit all these methods and signal if
External tool that uses |
Some action items after diagnostics meeting:
|
@cjihrig please take a look based on git blame it looks like you implemented big part of Based on my analysis it looks like we need created and initialized isolate only for I find that all report code is behind NODE_REPORT define, is it because this feature is experimental or it is part of design and by default node will be build without NODE_REPORT? If you think that the idea makes some sense, I will be happy to try to implement it. |
I anticipate that being removed once the feature is out of experimental. Even if it does remain, it's already enabled by default. That said, it means that some users might have it disabled.
I'm not sure what was said at the meeting. Can you comment on that? I do think we should add inspector information to the diagnostic report output, regardless of the outcome of this thread. I'm not sure how I feel about the idea of a |
IMO:
|
There is another important consideration: when we are running couple node processes in the same environment, it should not be possible by default for one process to find inspector websocket url of another process and connect to it. We consider inspector websocket url as unguessable one. We have one privileged node process which runs our tool and any number of other node processes which our tool needs to inspect. On tool side it should be possible to start all other node instances (including child processes) in a way when only tool can get access to their inspector websocket url. There are two ways to get inspector websocket url: parse With this test in mind I am not comfortable with putting inspector websocket url to report by default. Based on sensitivity of this information I prefer to have separate flag that enable and control how we store inspector websocket url, if we put this information to report, any further report related work requires having mentioned consideration in mind. Any user land solution in this case might be risky, if user land code can get instructions where to store information, it means that any other part of current node process can get this instructions and try to find there information about other node processes. With Reverse connection passed the test, there is only risk that someone can somehow kill server that listens for reverse connection and starts own server instead, it adds another requirement for demon to be run all the time. |
The argument takes the IPC path as an argument when it is passed, the inspector web socket server will send its full web socket url to IPC server with the given path at the start. This flag is required to solve inspector web socket url discovery the problem for child processes. Only one discovery option is available right now; it is searching for ws:// URLs in stderr of node process. This approach does not work when the parent process ignores the stderr of the child process, e.g. update-notifier uses this technique. Discussion about using files instead can be found here: nodejs/diagnostics#298
Since this problem still exists and ndb (and any other tool that needs to debug child processes) suffers without proposed flag. I would like to propose alternative solution. In addition to files Node.js implements IPC socket and server for IPC communications so my new pull request implements Any thoughts? |
This is exactly what easy-attach is doing. It does not use |
|
@ak239 You can still inject |
@hediet If we already publish In general we can workaround a lot of things, the question here how friendly platform should be for tools. |
@hediet I thought about your solution a little bit more and I think that there is no proper way to emulate sync waiting for debugger to connect except
This contract is crucial to avoid possible race conditions. Node is not processing any inspector related activity when it is blocked on any sync call. I believe that you added
|
@ak239 That sounds nice, thanks man :) I will definitely explore the |
With the recent |
@ak239 thanks, I use |
Hi,
I'd like to propose a solution for following problem: how to discover inspector web socket URL for locally running node instances. Imagine we have a tool that inspects all running node instances and capture some information using inspector protocol. It might be process and its child processes or set of independent node processes.
When we have more then one process to inspect they can not use the same port, so there is no way to define this port ahead of time So we need to pass 0 as port to allow node find free port for inspector by itself. We can pass it using environment and then all processes started with this flag will get own port.
In case of child process we still can parse stderr and try to find magic line that contains full WebSocket URL. It works only when we control process that we would like to start. In a lot of cases it is not convenient or not possible, e.g. we'd like to debug
npm run test
command as is without passing it to some magic runner script.So I would like to propose new node flag
--inspect-store
which takes a folder as argument. When this flag is passed directly or using NODE_OPTIONS, every time when inspector server started in node it will put specialrandom-id
file to passed folder. File will contain dump of /json/list endpoint (it contains some information about node including process title and inspector web socket URL). When inspector server finished node will try to remove this file without strict contract - tools that use this flag should be ready for stale files inside and should cleanup this folder after it is finished.I prefer this flag to be implemented in native node code to avoid any pollution of node runtime with some user land code, e.g. we can use inspector module to actually start inspector, get its url and save to file but it will force loading of inspector and fs modules that can change program behavior with and without inspection.
As alternative we might consider implementing some kind of inspector port that can be predicted but in this case tool will need to constantly ping different ports and waste CPU time.
Another alternative: we can add flag that forces node to send inspector web socket URL back using some channel, e.g. by sending get request to given URL. It requires daemon that should always be available in background. This solution sound more complicated to me than
--inspector-store
flag.PoC: nodejs/node#27605
The text was updated successfully, but these errors were encountered: