-
Notifications
You must be signed in to change notification settings - Fork 29.8k
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
src: fix Worker termination in inspector.waitForDebugger
#52527
src: fix Worker termination in inspector.waitForDebugger
#52527
Conversation
Signed-off-by: Daeyeon Jeong <[email protected]>
/cc @nodejs/cpp-reviewers @nodejs/inspector @nodejs/workers |
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 analysis!
Signed-off-by: Daeyeon Jeong <[email protected]>
Signed-off-by: Daeyeon Jeong <[email protected]>
This comment was marked as outdated.
This comment was marked as outdated.
Signed-off-by: Daeyeon Jeong <[email protected]>
This comment was marked as outdated.
This comment was marked as outdated.
await new Promise((r) => setTimeout(r, 2_000)); | ||
|
||
process.on('exit', (status) => assert.strictEqual(status, 0)); | ||
process.exit(); |
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 suggest merging the test cases - start worker # 1, terminate it, start worker # 2, call
process.exit
- What would happen if the main thread runs to completion? Would the worker just stay hanging? I don't remember details, would the WebSocket server shut down when the main thread completes and there's no ongoing sessions?
I believe the broader question is if inspector.waitForDebugger
even makes sense for workers. The way I remember target domain is you either specify autoattach so existing session would attach to newly created workers, or workers just start and sessions are attached whenever.
In the first case (autoattach) worker should only wait if there are connected sessions that asked to be attached to workers.
In the second case worker do not need to wait.
I apologize if I am not making sense, haven't worked on this in years...
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.
(Feel free to dismiss my comments as I am not sure I am up to date with the current state of inspector)
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 the broader question is if
inspector.waitForDebugger
even makes sense for workers. The way I remember target domain is you either specify autoattach so existing session would attach to newly created workers, or workers just start and sessions are attached whenever.
As far as I know, inspector.waitForDebugger
is the only working way to (programatically) debug Workers. #26609 (comment)
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 suggest merging the test cases
Applied.
What would happen if the main thread runs to completion?
If the main thread runs to completion (assuming it runs without process.exit()
in this test), then the WS server doesn't shut down, leaving the worker hanging.
Users seem to be using inspector.waitForDebugger
as a valid workaround for now. I did several tries, but autoattach doesn't seem to 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.
Ack. Thank you for the explanations.
// inspector.waitForDebugger(). | ||
if (isMainThread) { | ||
const worker = new Worker(fileURLToPath(import.meta.url)); | ||
await new Promise((r) => setTimeout(r, 2_000)); |
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.
Using timeout to wait until a worker is ready can be flaky on slow CI machines.
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 be more stable approach:
// Flags: --inspect=0
import * as common from '../common/index.mjs';
common.skipIfInspectorDisabled();
-import { isMainThread, Worker } from 'node:worker_threads';
+import { isMainThread, parentPort, Worker } from 'node:worker_threads';
import { fileURLToPath } from 'node:url';
import inspector from 'node:inspector';
// Ref: https://github.com/nodejs/node/issues/52467
// - worker.terminate() should terminate the worker and the pending
// inspector.waitForDebugger().
if (isMainThread) {
const worker = new Worker(fileURLToPath(import.meta.url));
- await new Promise((r) => setTimeout(r, 2_000));
+ await new Promise((r) => worker.on("message", r));
worker.on('exit', common.mustCall());
await worker.terminate();
} else {
inspector.open();
+ parentPort.postMessage("inspector is open")
inspector.waitForDebugger();
}
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.
Updated using MessagePort
. Thanks. PTAL.
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.
Using MessagePort doesn't seem to be enough. I tried using common.platformTimeout()
to adjust the timeout to give the worker more time.
Signed-off-by: Daeyeon Jeong <[email protected]>
Signed-off-by: Daeyeon Jeong <[email protected]>
This comment was marked as outdated.
This comment was marked as outdated.
Signed-off-by: Daeyeon Jeong <[email protected]>
This comment was marked as outdated.
This comment was marked as outdated.
…ions Signed-off-by: Daeyeon Jeong <[email protected]>
Changed the test to
|
This comment was marked as outdated.
This comment was marked as outdated.
…xpectations Signed-off-by: Daeyeon Jeong <[email protected]>
Landed in ac5f8f0 |
Signed-off-by: Daeyeon Jeong <[email protected]> PR-URL: #52527 Fixes: #52467 Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: Rich Trott <[email protected]> Reviewed-By: Kohei Ueno <[email protected]>
Signed-off-by: Daeyeon Jeong <[email protected]> PR-URL: #52527 Fixes: #52467 Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: Rich Trott <[email protected]> Reviewed-By: Kohei Ueno <[email protected]>
Signed-off-by: Daeyeon Jeong <[email protected]> PR-URL: #52527 Fixes: #52467 Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: Rich Trott <[email protected]> Reviewed-By: Kohei Ueno <[email protected]>
Signed-off-by: Daeyeon Jeong <[email protected]> PR-URL: #52527 Fixes: #52467 Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: Rich Trott <[email protected]> Reviewed-By: Kohei Ueno <[email protected]>
Signed-off-by: Daeyeon Jeong <[email protected]> PR-URL: nodejs#52527 Fixes: nodejs#52467 Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: Rich Trott <[email protected]> Reviewed-By: Kohei Ueno <[email protected]>
Signed-off-by: Daeyeon Jeong <[email protected]> PR-URL: nodejs#52527 Fixes: nodejs#52467 Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: Rich Trott <[email protected]> Reviewed-By: Kohei Ueno <[email protected]>
Fixes: #52467
When calling
inspector.waitForDebugger()
on a worker thread, it waits synchronously for debugger to connect using a conditional variable,incoming_message_cond_
. In this state, the worker thread cannot be terminated by the main thread.This patch adds a way to exit the wait state when node process exits.
Signed-off-by: Daeyeon Jeong [email protected]