-
Notifications
You must be signed in to change notification settings - Fork 30.1k
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
inspector: allow --inspect=host:port from js #13228
Conversation
c6df413
to
0b0a3ec
Compare
doc/api/inspector.md
Outdated
Return the UUID string of the listener, or undefined if the listener is not | ||
started. | ||
|
||
### ws.host([newHost]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
technically, there are 2 objects here. the configuration, which can have a getter and setter (or a unified function like I did here), and that actual running listener (if it is running). its not possible to change the port on the fly, the current listener would have only a getter. So, there could be 3 functions... or one, like here, and a warning that the new value won't take effect until a new listener is started. Thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure ws should be a singleton.
Implementation-wise we can listen on multiple ports. Also, we were considering a pipe transport in addition to the WS transport for scenarios like subprocesses.
So, maybe expose in API support for multiple "servers"? Then you would start a server on a different port and shutdown the one that was running before.
doc/api/inspector.md
Outdated
### ws.url.ws() | ||
|
||
Return a websocket URL that can be used to connect to the listener with | ||
a debugger that supports the inspect protocol. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this could also be ws.url()
, its just a simple ws://host:port/uuid
string.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be just a property
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would have to be at least a getter (the UUID isn't constant, it changes every time the server socket is closed).
doc/api/inspector.md
Outdated
|
||
### ws.url.chrome() | ||
|
||
Return a chrome devtools URL that can be used to open the Chrome debugger |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this URL is long, complex, and chrome specific, which is why I think having a method to insulate us from that is useful. Then again, these URL helpers are sugar, people can always construct the URLs themselves from host, port, UUID. Thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this API is not necessary - exactly because the URL can be reconstructed based on parameters.
lib/inspector.js
Outdated
id: wsId, | ||
listen: wsListen, | ||
unlisten: process._debugEnd, | ||
// XXX find a way to just stop Io thread, not entire agent, so ID can be stable? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@eugeneo Am I thinking of it wrong? Would it be useful to have a way to stop the listener thread, then be able to start it again later with the same UUID? Or does it just not matter? I'm not sure what the UUID is supposed to identify, but if its a single still-living instance of the same process, then it should be persistent (debugEnd clears it). If its supposed to identify a specific instance of an agent listening on a TCP port, and change when the port is closed, the current behaviour is fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
UUID is there for security, so web sites are not able to connect to Node instances running locally. So it does not represent anything.
It would likely be convinient if it stayed stable over the life of the Node process, but it does not matter much.
Thanks for looking into this! I was planning to start a discussion about similar APIs. I believe it would be best to always start WS server from JS code (probably from the node_bootstrap.js). |
(Sorry, thought that button clears the comment field) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for looking into this. I think we need some discussion to align the plans for the inspector future.
doc/api/inspector.md
Outdated
allow programatic control of the websocket, equivalent to use `--inspect*` CLI | ||
options. | ||
|
||
### ws.listen() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe ws.listen(waitForFrontend[, host][, port])?
Also, I feel like the agent should always be started from JavaScript - node_bootstrap.js or something can call ws.listen based on command line arguments.
I was planning exposing something like inspector.onDebugSignal(callback)
that would allow developers to customize WS server startup - e.g. to start a server on a different port.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What would the waitForFrontend
argument be? What would it do?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be a boolean, and it would block the main thread until a debug client connects to the ws port and initiates a session, equivalent to the wait_for_connect
boolean option of InspectorIo
.
doc/api/inspector.md
Outdated
Return the UUID string of the listener, or undefined if the listener is not | ||
started. | ||
|
||
### ws.host([newHost]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure ws should be a singleton.
Implementation-wise we can listen on multiple ports. Also, we were considering a pipe transport in addition to the WS transport for scenarios like subprocesses.
So, maybe expose in API support for multiple "servers"? Then you would start a server on a different port and shutdown the one that was running before.
doc/api/inspector.md
Outdated
|
||
### ws.url.chrome() | ||
|
||
Return a chrome devtools URL that can be used to open the Chrome debugger |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this API is not necessary - exactly because the URL can be reconstructed based on parameters.
lib/inspector.js
Outdated
id: wsId, | ||
listen: wsListen, | ||
unlisten: process._debugEnd, | ||
// XXX find a way to just stop Io thread, not entire agent, so ID can be stable? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
UUID is there for security, so web sites are not able to connect to Node instances running locally. So it does not represent anything.
It would likely be convinient if it stayed stable over the life of the Node process, but it does not matter much.
lib/internal/cluster/master.js
Outdated
@@ -72,6 +72,7 @@ cluster.setupMaster = function(options) { | |||
|
|||
process.nextTick(setupSettingsNT, settings); | |||
|
|||
// XXX cluster masters turn debug on in all children? does that work? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe there are tests for that. I distinctly remember having to deal with them :)
src/inspector_agent.cc
Outdated
@@ -667,6 +669,51 @@ void Agent::PauseOnNextJavascriptStatement(const std::string& reason) { | |||
channel->schedulePauseOnNextStatement(reason); | |||
} | |||
|
|||
void WsListen(const FunctionCallbackInfo<Value>& args) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like Ws* bindings should be in the inspector_io.cc.
UUID may belong to inspector (it now lives pretty much as long as Node
process lives) and become another ctor argument for the io.
Another thing I've been thinking about - what if Inspector WS was a module?
It will still need native code and another thread (as it needs to work
while main thread is paused on a breakpoint) but it could use JS bindings
to talk to the inspector backend.
…On Thu, May 25, 2017 at 7:19 PM Sam Roberts ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In lib/inspector.js
<#13228 (comment)>:
> module.exports = {
+ ws: {
+ id: wsId,
+ listen: wsListen,
+ unlisten: process._debugEnd,
+ // XXX find a way to just stop Io thread, not entire agent, so ID can be stable?
@eugeneo <https://github.com/eugeneo> Am I thinking of it wrong? Would it
be useful to have a way to stop the listener thread, then be able to start
it again later with the same UUID? Or does it just not matter? I'm not sure
what the UUID is supposed to identify, but if its a single still-living
instance of the same process, then it should be persistent (debugEnd clears
it). If its supposed to identify a specific instance of an agent listening
on a TCP port, and change when the port is closed, the current behaviour is
fine.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#13228 (review)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AARkrT3a1vlPp7WUJMz7E08PN76i-Q25ks5r9ja4gaJpZM4NnGAk>
.
|
@sam-github - I would start a discussion before landing this - #13247 I am wondering if this server should be separate from the core inspector. |
0b0a3ec
to
8d06ca1
Compare
doc/api/inspector.md
Outdated
The Inspector can be interacted with via a websocket-based protocol. These APIs | ||
allow programatic control of the websocket, equivalent to use `--inspect*` CLI | ||
options. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am very hesitant to do this. If we expose an API for this, then we need to make certain that this cannot be used for anything other than interaction via the Inspector protocol.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It can't be. As is, all this PR does (ATM) is allow instead of forcing --inspect
to be provided as a CLI option, it allows node to startup, and then the js API calls the same C++ APIs called to turn on the listener that would have been called if --inspect
had been provided. There is zero general purpose protocol or websocket capability exposed.
doc/api/inspector.md
Outdated
Start the websocket listener. | ||
|
||
### ws.unlisten() | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ws.close()
is more idiomatic and consistent
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok. though it sounds like @eugeneo is looking for quite a different API, this is more of a POC at the moment.
doc/api/inspector.md
Outdated
### ws.id() | ||
|
||
Return the UUID string of the listener, or undefined if the listener is not | ||
started. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should just make this a property.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe you think its a single unchanging value? But it isn't, if you run start.js you'll see 2 or 4 values of this UUID printed. So, it could be a getter, but not a fixed-value property.
doc/api/inspector.md
Outdated
### ws.port([newPort]) | ||
|
||
* port {number} Set a new port to bind to (will not effect a currently | ||
started listener). Optional. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If there is an existing listener that is bound to a port, what happens?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
right now, nothing, it has no effect (until the listeners is closed and listen is called again).
lib/inspector.js
Outdated
function addr() { | ||
const id = wsId(); | ||
if (!id) | ||
throw new Error('inspector did not start'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If introducing new errors, please use internal/errors
lib/inspector.js
Outdated
} | ||
|
||
function wsUrl() { | ||
return 'ws://' + addr(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
`ws://${addr()}`
likewise for chromeUrl?
start.js
Outdated
@@ -0,0 +1,39 @@ | |||
const assert = require('assert'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume this file wasn't supposed to be checked in?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Its a WIP, this would eventually be test code, but it shows how to call the APIs for now.
8d06ca1
to
3169ee5
Compare
09cfba7
to
a86f3f5
Compare
PR-URL: nodejs#13228 Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
a86f3f5
to
2791b36
Compare
Marking this as semver-minor post landing. If anyone feels this is incorrect, let me know |
Isn't the |
PR-URL: #13228 Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
@@ -83,5 +83,8 @@ class Session extends EventEmitter { | |||
} | |||
|
|||
module.exports = { | |||
open: (port, host, wait) => open(port, host, !!wait), | |||
close: process._debugEnd, | |||
url: url, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Re: #9659 I now think this should have been a URL
not a string...
Retrospectively document the changes history of the `inspector.close` API. PR-URL: #44628 Refs: #44489 Refs: #13228 Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com> Reviewed-By: Daeyeon Jeong <daeyeon.dev@gmail.com> Reviewed-By: Kohei Ueno <kohei.ueno119@gmail.com>
Retrospectively document the changes history of the `inspector.close` API. PR-URL: nodejs#44628 Refs: nodejs#44489 Refs: nodejs#13228 Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com> Reviewed-By: Daeyeon Jeong <daeyeon.dev@gmail.com> Reviewed-By: Kohei Ueno <kohei.ueno119@gmail.com>
Retrospectively document the changes history of the `inspector.close` API. PR-URL: #44628 Refs: #44489 Refs: #13228 Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com> Reviewed-By: Daeyeon Jeong <daeyeon.dev@gmail.com> Reviewed-By: Kohei Ueno <kohei.ueno119@gmail.com>
Retrospectively document the changes history of the `inspector.close` API. PR-URL: #44628 Refs: #44489 Refs: #13228 Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com> Reviewed-By: Daeyeon Jeong <daeyeon.dev@gmail.com> Reviewed-By: Kohei Ueno <kohei.ueno119@gmail.com>
Retrospectively document the changes history of the `inspector.close` API. PR-URL: #44628 Refs: #44489 Refs: #13228 Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com> Reviewed-By: Daeyeon Jeong <daeyeon.dev@gmail.com> Reviewed-By: Kohei Ueno <kohei.ueno119@gmail.com>
Retrospectively document the changes history of the `inspector.close` API. PR-URL: #44628 Refs: #44489 Refs: #13228 Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com> Reviewed-By: Daeyeon Jeong <daeyeon.dev@gmail.com> Reviewed-By: Kohei Ueno <kohei.ueno119@gmail.com>
Retrospectively document the changes history of the `inspector.close` API. PR-URL: #44628 Refs: #44489 Refs: #13228 Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com> Reviewed-By: Daeyeon Jeong <daeyeon.dev@gmail.com> Reviewed-By: Kohei Ueno <kohei.ueno119@gmail.com>
Retrospectively document the changes history of the `inspector.close` API. PR-URL: #44628 Refs: #44489 Refs: #13228 Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com> Reviewed-By: Daeyeon Jeong <daeyeon.dev@gmail.com> Reviewed-By: Kohei Ueno <kohei.ueno119@gmail.com>
Retrospectively document the changes history of the `inspector.close` API. PR-URL: #44628 Refs: #44489 Refs: #13228 Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com> Reviewed-By: Daeyeon Jeong <daeyeon.dev@gmail.com> Reviewed-By: Kohei Ueno <kohei.ueno119@gmail.com>
Retrospectively document the changes history of the `inspector.close` API. PR-URL: #44628 Refs: #44489 Refs: #13228 Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com> Reviewed-By: Daeyeon Jeong <daeyeon.dev@gmail.com> Reviewed-By: Kohei Ueno <kohei.ueno119@gmail.com>
Retrospectively document the changes history of the `inspector.close` API. PR-URL: #44628 Refs: #44489 Refs: #13228 Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com> Reviewed-By: Daeyeon Jeong <daeyeon.dev@gmail.com> Reviewed-By: Kohei Ueno <kohei.ueno119@gmail.com>
Retrospectively document the changes history of the `inspector.close` API. PR-URL: nodejs/node#44628 Refs: nodejs/node#44489 Refs: nodejs/node#13228 Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com> Reviewed-By: Daeyeon Jeong <daeyeon.dev@gmail.com> Reviewed-By: Kohei Ueno <kohei.ueno119@gmail.com>
Retrospectively document the changes history of the `inspector.close` API. PR-URL: nodejs/node#44628 Refs: nodejs/node#44489 Refs: nodejs/node#13228 Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com> Reviewed-By: Daeyeon Jeong <daeyeon.dev@gmail.com> Reviewed-By: Kohei Ueno <kohei.ueno119@gmail.com>
Use case is to be able to turn on/off the inspector websocket port, control the port and host it binds to, and determine the current UUID, so that information can be transmitted out-of-band to remote inspect clients.
/to @eugeneo , this builds on top of your recent work on js APIs for the inspector.
/to @nodejs/diagnostics As discussed in last WG meeting.
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passesAffected core subsystem(s)
src, inspector