inspector: report all workers

Main thread (the one that WS endpoint connects to) should be able
to report all workers.

PR-URL: https://github.com/nodejs/node/pull/28872
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
This commit is contained in:
Eugene Ostroukhov 2019-07-26 16:38:15 -07:00 committed by Rich Trott
parent c3b2111423
commit 7435dc8b2b
4 changed files with 108 additions and 9 deletions

View File

@ -55,6 +55,13 @@ class ParentInspectorHandle {
std::shared_ptr<MainThreadHandle> parent_thread,
bool wait_for_connect);
~ParentInspectorHandle();
std::unique_ptr<ParentInspectorHandle> NewParentInspectorHandle(
int thread_id, const std::string& url) {
return std::make_unique<ParentInspectorHandle>(thread_id,
url,
parent_thread_,
wait_);
}
void WorkerStarted(std::shared_ptr<MainThreadHandle> worker_thread,
bool waiting);
bool WaitForConnect() {

View File

@ -237,8 +237,10 @@ class ChannelImpl final : public v8_inspector::V8Inspector::Channel,
tracing_agent_ =
std::make_unique<protocol::TracingAgent>(env, main_thread_);
tracing_agent_->Wire(node_dispatcher_.get());
worker_agent_ = std::make_unique<protocol::WorkerAgent>(worker_manager);
worker_agent_->Wire(node_dispatcher_.get());
if (worker_manager) {
worker_agent_ = std::make_unique<protocol::WorkerAgent>(worker_manager);
worker_agent_->Wire(node_dispatcher_.get());
}
runtime_agent_ = std::make_unique<protocol::RuntimeAgent>();
runtime_agent_->Wire(node_dispatcher_.get());
}
@ -246,8 +248,10 @@ class ChannelImpl final : public v8_inspector::V8Inspector::Channel,
~ChannelImpl() override {
tracing_agent_->disable();
tracing_agent_.reset(); // Dispose before the dispatchers
worker_agent_->disable();
worker_agent_.reset(); // Dispose before the dispatchers
if (worker_agent_) {
worker_agent_->disable();
worker_agent_.reset(); // Dispose before the dispatchers
}
runtime_agent_->disable();
runtime_agent_.reset(); // Dispose before the dispatchers
}
@ -670,6 +674,9 @@ class NodeInspectorClient : public V8InspectorClient {
}
std::shared_ptr<WorkerManager> getWorkerManager() {
if (!is_main_) {
return nullptr;
}
if (worker_manager_ == nullptr) {
worker_manager_ =
std::make_shared<WorkerManager>(getThreadHandle());
@ -968,7 +975,11 @@ void Agent::SetParentHandle(
std::unique_ptr<ParentInspectorHandle> Agent::GetParentHandle(
int thread_id, const std::string& url) {
return client_->getWorkerManager()->NewParentHandle(thread_id, url);
if (!parent_handle_) {
return client_->getWorkerManager()->NewParentHandle(thread_id, url);
} else {
return parent_handle_->NewParentInspectorHandle(thread_id, url);
}
}
void Agent::WaitForConnect() {

View File

@ -3,6 +3,7 @@
const common = require('../common');
common.skipIfInspectorDisabled();
common.skipIfWorker();
const assert = require('assert');
const { Worker } = require('worker_threads');
@ -12,9 +13,7 @@ const session = new Session();
let done = false;
session.connect();
session.on('NodeWorker.attachedToWorker', ({ params: { sessionId } }) => {
function onAttachToWorker({ params: { sessionId } }) {
let id = 1;
function postToWorkerInspector(method, params) {
session.post('NodeWorker.sendMessageToWorker', {
@ -47,7 +46,11 @@ session.on('NodeWorker.attachedToWorker', ({ params: { sessionId } }) => {
{ enabled: true });
// start worker
postToWorkerInspector('Runtime.runIfWaitingForDebugger');
});
}
session.connect();
session.on('NodeWorker.attachedToWorker', common.mustCall(onAttachToWorker));
session.post('NodeWorker.enable', { waitForDebuggerOnStart: true }, () => {
new Worker('console.log("Worker is done")', { eval: true })

View File

@ -0,0 +1,78 @@
'use strict';
const common = require('../common');
common.skipIfInspectorDisabled();
const { Worker, isMainThread, parentPort, workerData } =
require('worker_threads');
if (isMainThread || workerData !== 'launched by test') {
common.skipIfWorker();
}
const { Session } = require('inspector');
const MAX_DEPTH = 3;
let rootWorker = null;
const runTest = common.mustCall(function() {
let reportedWorkersCount = 0;
const session = new Session();
session.connect();
session.on('NodeWorker.attachedToWorker', common.mustCall(
({ params: { workerInfo } }) => {
console.log(`Worker ${workerInfo.title} was reported`);
if (++reportedWorkersCount === MAX_DEPTH) {
rootWorker.postMessage({ done: true });
}
}, MAX_DEPTH));
session.post('NodeWorker.enable', { waitForDebuggerOnStart: false });
});
function processMessage({ child }) {
console.log(`Worker ${child} is running`);
if (child === MAX_DEPTH) {
runTest();
}
}
function workerCallback(message) {
parentPort.postMessage(message);
}
function startWorker(depth, messageCallback) {
const worker = new Worker(__filename, { workerData: 'launched by test' });
worker.on('message', messageCallback);
worker.postMessage({ depth });
return worker;
}
function runMainThread() {
rootWorker = startWorker(1, processMessage);
}
function runChildWorkerThread() {
let worker = null;
parentPort.on('message', ({ child, depth, done }) => {
if (done) {
if (worker) {
worker.postMessage({ done: true });
}
parentPort.close();
} else if (depth) {
parentPort.postMessage({ child: depth });
if (depth < MAX_DEPTH) {
worker = startWorker(depth + 1, workerCallback);
}
} else if (child) {
parentPort.postMessage({ child });
}
});
}
if (isMainThread) {
runMainThread();
} else {
runChildWorkerThread();
}