Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 23119ca

Browse filesBrowse files
alexkozytargos
authored andcommitted
inspector: supported NodeRuntime domain in worker
NodeRuntime domain was introduced to give inspector client way to fetch captured information before Node process is gone. We need similar capability for work. With current protocol inspector client can force worker to wait on start by passing waitForDebuggerOnStart flag to NodeWorker.enable method. So client has some time to setup environment, e.g. start profiler. At the same time there is no way to prevent worker from being terminated. So we can start capturing profile but we can not reliably get captured data back. This PR implemented NodeRuntime.notifyWhenWaitingForDisconnect method for worker. When NodeRuntime.waitingForDisconnect notification is enabled, worker will wait for explicit NodeWorker.detach call. With this PR worker tooling story is nicely aligned with main thread tooling story. The only difference is that main thread by default is waiting for disconnect but worker thread is not waiting. Issue: #27677 PR-URL: #27706 Reviewed-By: Eugene Ostroukhov <eostroukhov@google.com>
1 parent 6a5ce36 commit 23119ca
Copy full SHA for 23119ca

File tree

Expand file treeCollapse file tree

6 files changed

+70
-10
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

6 files changed

+70
-10
lines changed
Open diff view settings
Collapse file

‎src/inspector/node_protocol.pdl‎

Copy file name to clipboardExpand all lines: src/inspector/node_protocol.pdl
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@ experimental domain NodeWorker
7171
# Detaches from all running workers and disables attaching to new workers as they are started.
7272
command disable
7373

74+
# Detached from the worker with given sessionId.
75+
command detach
76+
parameters
77+
SessionID sessionId
78+
7479
# Issued when attached to a worker.
7580
event attachedToWorker
7681
parameters
Collapse file

‎src/inspector/runtime_agent.cc‎

Copy file name to clipboardExpand all lines: src/inspector/runtime_agent.cc
-4Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,6 @@ void RuntimeAgent::Wire(UberDispatcher* dispatcher) {
1616
}
1717

1818
DispatchResponse RuntimeAgent::notifyWhenWaitingForDisconnect(bool enabled) {
19-
if (!env_->owns_process_state()) {
20-
return DispatchResponse::Error(
21-
"NodeRuntime domain can only be used through main thread sessions");
22-
}
2319
notify_when_waiting_for_disconnect_ = enabled;
2420
return DispatchResponse::OK();
2521
}
Collapse file

‎src/inspector/worker_agent.cc‎

Copy file name to clipboardExpand all lines: src/inspector/worker_agent.cc
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,11 @@ DispatchResponse WorkerAgent::disable() {
115115
return DispatchResponse::OK();
116116
}
117117

118+
DispatchResponse WorkerAgent::detach(const String& sessionId) {
119+
workers_->Detached(sessionId);
120+
return DispatchResponse::OK();
121+
}
122+
118123
void NodeWorkers::WorkerCreated(const std::string& title,
119124
const std::string& url,
120125
bool waiting,
Collapse file

‎src/inspector/worker_agent.h‎

Copy file name to clipboardExpand all lines: src/inspector/worker_agent.h
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ class WorkerAgent : public NodeWorker::Backend {
2525

2626
DispatchResponse enable(bool waitForDebuggerOnStart) override;
2727
DispatchResponse disable() override;
28+
DispatchResponse detach(const String& sessionId) override;
2829

2930
private:
3031
std::shared_ptr<NodeWorker::Frontend> frontend_;
Collapse file

‎src/inspector_agent.cc‎

Copy file name to clipboardExpand all lines: src/inspector_agent.cc
+12-6Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -472,8 +472,8 @@ class NodeInspectorClient : public V8InspectorClient {
472472
runMessageLoop();
473473
}
474474

475-
void waitForIoShutdown() {
476-
waiting_for_io_shutdown_ = true;
475+
void waitForSessionsDisconnect() {
476+
waiting_for_sessions_disconnect_ = true;
477477
runMessageLoop();
478478
}
479479

@@ -548,6 +548,8 @@ class NodeInspectorClient : public V8InspectorClient {
548548
}
549549
contextDestroyed(env_->context());
550550
}
551+
if (waiting_for_sessions_disconnect_ && !is_main_)
552+
waiting_for_sessions_disconnect_ = false;
551553
}
552554

553555
void dispatchMessageFromFrontend(int session_id, const StringView& message) {
@@ -678,8 +680,9 @@ class NodeInspectorClient : public V8InspectorClient {
678680
bool shouldRunMessageLoop() {
679681
if (waiting_for_frontend_)
680682
return true;
681-
if (waiting_for_io_shutdown_ || waiting_for_resume_)
683+
if (waiting_for_sessions_disconnect_ || waiting_for_resume_) {
682684
return hasConnectedSessions();
685+
}
683686
return false;
684687
}
685688

@@ -723,7 +726,7 @@ class NodeInspectorClient : public V8InspectorClient {
723726
int next_session_id_ = 1;
724727
bool waiting_for_resume_ = false;
725728
bool waiting_for_frontend_ = false;
726-
bool waiting_for_io_shutdown_ = false;
729+
bool waiting_for_sessions_disconnect_ = false;
727730
// Allows accessing Inspector from non-main threads
728731
std::unique_ptr<MainThreadInterface> interface_;
729732
std::shared_ptr<WorkerManager> worker_manager_;
@@ -819,11 +822,14 @@ void Agent::WaitForDisconnect() {
819822
fprintf(stderr, "Waiting for the debugger to disconnect...\n");
820823
fflush(stderr);
821824
}
822-
if (!client_->notifyWaitingForDisconnect())
825+
if (!client_->notifyWaitingForDisconnect()) {
823826
client_->contextDestroyed(parent_env_->context());
827+
} else if (is_worker) {
828+
client_->waitForSessionsDisconnect();
829+
}
824830
if (io_ != nullptr) {
825831
io_->StopAcceptingNewConnections();
826-
client_->waitForIoShutdown();
832+
client_->waitForSessionsDisconnect();
827833
}
828834
}
829835

Collapse file

‎test/parallel/test-worker-debug.js‎

Copy file name to clipboardExpand all lines: test/parallel/test-worker-debug.js
+47Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,52 @@ async function testTwoWorkers(session, post) {
206206
await Promise.all([worker1Exited, worker2Exited]);
207207
}
208208

209+
async function testWaitForDisconnectInWorker(session, post) {
210+
console.log('Test NodeRuntime.waitForDisconnect in worker');
211+
212+
const sessionWithoutWaiting = new Session();
213+
sessionWithoutWaiting.connect();
214+
const sessionWithoutWaitingPost = doPost.bind(null, sessionWithoutWaiting);
215+
216+
await sessionWithoutWaitingPost('NodeWorker.enable', {
217+
waitForDebuggerOnStart: true
218+
});
219+
await post('NodeWorker.enable', { waitForDebuggerOnStart: true });
220+
221+
const attached = [
222+
waitForWorkerAttach(session),
223+
waitForWorkerAttach(sessionWithoutWaiting)
224+
];
225+
226+
let worker = null;
227+
const exitPromise = runWorker(2, (w) => worker = w);
228+
229+
const [{ sessionId: sessionId1 }, { sessionId: sessionId2 }] =
230+
await Promise.all(attached);
231+
232+
const workerSession1 = new WorkerSession(session, sessionId1);
233+
const workerSession2 = new WorkerSession(sessionWithoutWaiting, sessionId2);
234+
235+
await workerSession2.post('Runtime.enable');
236+
await workerSession1.post('Runtime.enable');
237+
await workerSession1.post('NodeRuntime.notifyWhenWaitingForDisconnect', {
238+
enabled: true
239+
});
240+
await workerSession1.post('Runtime.runIfWaitingForDebugger');
241+
242+
worker.postMessage('resume');
243+
244+
await waitForEvent(workerSession1, 'NodeRuntime.waitingForDisconnect');
245+
post('NodeWorker.detach', { sessionId: sessionId1 });
246+
await waitForEvent(workerSession2, 'Runtime.executionContextDestroyed');
247+
248+
await exitPromise;
249+
250+
await post('NodeWorker.disable');
251+
await sessionWithoutWaitingPost('NodeWorker.disable');
252+
sessionWithoutWaiting.disconnect();
253+
}
254+
209255
async function test() {
210256
const session = new Session();
211257
session.connect();
@@ -219,6 +265,7 @@ async function test() {
219265

220266
await testNoWaitOnStart(session, post);
221267
await testTwoWorkers(session, post);
268+
await testWaitForDisconnectInWorker(session, post);
222269

223270
session.disconnect();
224271
console.log('Test done');

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.