-
Notifications
You must be signed in to change notification settings - Fork 734
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
refactor: inspect/debugging as useInspector
#199
Conversation
🦋 Changeset detectedLatest commit: e3fa749 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
a5f787f
to
16a1298
Compare
useInspector(token ? token.inspectorUrl.href : undefined); | ||
useInspector({ | ||
inspectorUrl: token ? token.inspectorUrl.href : undefined, | ||
port: 9229, |
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.
in a followup PR, we'll make this port configurable
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.
And/or also if not configured, dynamic to avoid an already open port?
16a1298
to
a2b5f16
Compare
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 love the use of hooks here to keep dependencies in sync. Very nice!
I made a bunch of comments, but I don't think any are blocking this PR, assuming that you have actually checked it works as expected!
Can you provide some thoughts on how you propose we write tests for all this functionality?
@@ -196,7 +162,11 @@ function Remote(props: { | |||
|
|||
useProxy({ token, publicRoot: props.public, port: props.port }); | |||
|
|||
useInspector(token ? token.inspectorUrl.href : undefined); | |||
useInspector({ | |||
inspectorUrl: token ? token.inspectorUrl.href : undefined, |
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.
NIT:
inspectorUrl: token ? token.inspectorUrl.href : undefined, | |
inspectorUrl: token?.inspectorUrl.href, |
packages/wrangler/src/inspect.ts
Outdated
* When we start a session with `wrangler dev`, the Workers platform | ||
* also exposes a debugging websocket that implements the DevTools | ||
* Protocol. While we could just start up DevTools and connect to this | ||
* URL, however that URL changes every time we make a change to the |
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.
* URL, however that URL changes every time we make a change to the | |
* URL, that URL changes every time we make a change to the |
useInspector(token ? token.inspectorUrl.href : undefined); | ||
useInspector({ | ||
inspectorUrl: token ? token.inspectorUrl.href : undefined, | ||
port: 9229, |
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.
And/or also if not configured, dynamic to avoid an already open port?
packages/wrangler/src/inspect.ts
Outdated
// Let's create the websocket server on top of the proxy server | ||
wsServerRef.current = new WebSocketServer({ server: serverRef.current }); | ||
wsServerRef.current.on("connection", (ws: WebSocket) => { | ||
if (isConnected) { |
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.
Could you do something like the following?
if (wsServerRef.current.clients.size > 1) {
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.
nice. will do.
packages/wrangler/src/inspect.ts
Outdated
*/ | ||
let isConnected = false; | ||
// Let's create the websocket server on top of the proxy server | ||
wsServerRef.current = new WebSocketServer({ server: serverRef.current }); |
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.
According to this https://github.com/websockets/ws/blob/HEAD/doc/ws.md#serverclients we need to set clientTracking: true
in these options so that the clients
property used below is active.
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.
Huh, I could swear I tested this. Thanks for the catch!
packages/wrangler/src/inspect.ts
Outdated
messageBufferRef.current.forEach((evt) => { | ||
localWebSocket.send(evt); | ||
}); |
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.
And if we renamed remoteMessageListener
to sendMessageToLocal
then it would have been more obvious to reuse that here:
messageBufferRef.current.forEach((evt) => { | |
localWebSocket.send(evt); | |
}); | |
messageBufferRef.current.forEach(sendMessageToLocal); |
packages/wrangler/src/inspect.ts
Outdated
|
||
/** | ||
* This function converts a message serialised as a devtools event | ||
* into aarguments uitable to be called by a console method, and |
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.
* into aarguments uitable to be called by a console method, and | |
* into arguments suitable to be called by a console method, and |
} | ||
} | ||
|
||
console[evt.type](...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.
Given that this is running in ink, I wonder if we could pass these messages out to be rendered in an Ink component, rather than just dumping them out using console.xxx
?
(I appreciate that Ink patches console
but I think we could be more elegant here...
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.
We can revisit it. I actually try to avoid Ink for anything that doesn't feel like UI (and before you say it, I understand the boudnary is deeply fuzzy.) For example, in this usecase, I want the messages to persist no matter what, even if the process exits, etc. For now I think calling console
methods makes sense, and matches behaviour closer to node (or at least, is already better than what we have, which is nothing.)
packages/wrangler/src/inspect.ts
Outdated
wsServerRef.current = new WebSocketServer({ server: serverRef.current }); | ||
wsServerRef.current.on("connection", (ws: WebSocket) => { | ||
if (isConnected) { | ||
console.log( |
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.
console.warn
or console.error
here?
}, 10_000); | ||
}); | ||
|
||
ws.on("unexpected-response", () => { |
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.
Is this just something that you have noticed or is it documented somewhere?
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.
Noticed! It actually happens. Tho, good point, it's not in the spec. I wonder whether we do anything special here for this message. I'll investigate.
a2b5f16
to
16ff859
Compare
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 updated the PR with suggested changes. I'm going to write down some followup tasks, including testing plan, before I land this. Thanks @petebacondarwin!
}, 10_000); | ||
}); | ||
|
||
ws.on("unexpected-response", () => { |
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.
Noticed! It actually happens. Tho, good point, it's not in the spec. I wonder whether we do anything special here for this message. I'll investigate.
packages/wrangler/src/inspect.ts
Outdated
// TODO: maybe we should have a max limit on this? | ||
// if so, we should be careful when removing messages | ||
// from the front, because they could be critical for | ||
// devtools (like execution context creation, etc) |
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.
Actually in my tests, there don't seem to be any critical messages per se. But I could be mistaken. Let's revisit this when it becomes a problem.
packages/wrangler/src/inspect.ts
Outdated
*/ | ||
let isConnected = false; | ||
// Let's create the websocket server on top of the proxy server | ||
wsServerRef.current = new WebSocketServer({ server: serverRef.current }); |
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.
Huh, I could swear I tested this. Thanks for the catch!
packages/wrangler/src/inspect.ts
Outdated
// Let's create the websocket server on top of the proxy server | ||
wsServerRef.current = new WebSocketServer({ server: serverRef.current }); | ||
wsServerRef.current.on("connection", (ws: WebSocket) => { | ||
if (isConnected) { |
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.
nice. will do.
* of the effect that connects to the remote websocket. | ||
*/ | ||
const [ | ||
retryRemoteWebSocketConnectionSigil, |
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 want a good word for something that's used to trigger the effect again. A sigil is used through history as a sign/seal of something. I would say counter, but that's the implementation detail. Got any suggestions for something better?
try { | ||
remoteWebSocket.send(event.data); | ||
} catch (e) { | ||
if (e.message !== "WebSocket is not open: readyState 0 (CONNECTING)") { |
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.
The message is brittle. I highly dount it's part of the spec. Honestly maybe this can just be silent. When I add a logger for #230 I'll revisit this. Leaving this conversation unresolved so I can find it later.
} | ||
} | ||
|
||
console[evt.type](...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.
We can revisit it. I actually try to avoid Ink for anything that doesn't feel like UI (and before you say it, I understand the boudnary is deeply fuzzy.) For example, in this usecase, I want the messages to persist no matter what, even if the process exits, etc. For now I think calling console
methods makes sense, and matches behaviour closer to node (or at least, is already better than what we have, which is nothing.)
16ff859
to
0f0dea4
Compare
This PR rewrites the logic for establishing a connection with the debugging socket, and adds some enhancements along the way. Part of solving #188. Some highlights - - I've installed `"devtools-protocol`, a convenient package that has the static types for the devtools protocol (duh) autogenerated from chrome's devtools codebase. - We now log messages and exceptions into the terminal directly, so you don't have to open devtools to see those messages. - Messages are now buffered until a devtools instance connects, so you won't lose any messages while devtools isn't connected. - We don't lose the connection on making changes to the worker, removing the need for the kludgy hack on the devtools side (where we refresh the whole page when there's a change) Some things that I still have to do, and will do so in followup PRs - - clear the console whenever we make a change to the worker - stay connected when we shift between local/remote mode - eventually, move to using the devtools hosted at cloudflareworkers.com.
0f0dea4
to
e3fa749
Compare
This PR rewrites the logic for establishing a connection with the debugging socket, and adds some enhancements along the way. Part of solving #188. Some highlights -
devtools-protocol
, a convenient package that has the static types for the devtools protocol (duh) autogenerated from chrome's devtools codebase.Some things that I still have to do in followup PRs -