Skip to content

Commit b67a8fb

Browse files
cola119aduh95
authored andcommitted
inspector: add Target.getTargets and extract TargetManager
PR-URL: #62487 Reviewed-By: Ryuhei Shima <shimaryuhei@gmail.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
1 parent 95c7fc6 commit b67a8fb

File tree

8 files changed

+190
-40
lines changed

8 files changed

+190
-40
lines changed

src/inspector/domain_target.pdl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ experimental domain Target
2020
SessionID sessionId
2121
TargetInfo targetInfo
2222
boolean waitingForDebugger
23+
command getTargets
24+
returns
25+
array of TargetInfo targetInfos
2326
command setAutoAttach
2427
parameters
2528
boolean autoAttach

src/inspector/node_inspector.gypi

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
'src/inspector/network_inspector.h',
3333
'src/inspector/network_agent.cc',
3434
'src/inspector/network_agent.h',
35+
'src/inspector/target_manager.cc',
36+
'src/inspector/target_manager.h',
3537
'src/inspector/target_agent.cc',
3638
'src/inspector/target_agent.h',
3739
'src/inspector/worker_inspector.cc',

src/inspector/target_agent.cc

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,6 @@ namespace node {
88
namespace inspector {
99
namespace protocol {
1010

11-
std::unordered_map<int, std::shared_ptr<MainThreadHandle>>
12-
TargetAgent::target_session_id_worker_map_ =
13-
std::unordered_map<int, std::shared_ptr<MainThreadHandle>>();
14-
int TargetAgent::next_session_id_ = 1;
1511
class WorkerTargetDelegate : public WorkerDelegate {
1612
public:
1713
explicit WorkerTargetDelegate(std::shared_ptr<TargetAgent> target_agent)
@@ -32,13 +28,14 @@ std::unique_ptr<Target::TargetInfo> createTargetInfo(
3228
const std::string_view target_id,
3329
const std::string_view type,
3430
const std::string_view title,
35-
const std::string_view url) {
31+
const std::string_view url,
32+
bool attached = false) {
3633
return Target::TargetInfo::create()
3734
.setTargetId(std::string(target_id))
3835
.setType(std::string(type))
3936
.setTitle(std::string(title))
4037
.setUrl(std::string(url))
41-
.setAttached(false)
38+
.setAttached(attached)
4239
.setCanAccessOpener(true)
4340
.build();
4441
}
@@ -57,11 +54,11 @@ void TargetAgent::createAndAttachIfNecessary(
5754

5855
targetCreated(target_id, type, title, url);
5956
bool attached = false;
60-
if (auto_attach_) {
57+
if (target_manager_->auto_attach()) {
6158
attached = true;
6259
attachedToTarget(worker, target_id, type, title, url);
6360
}
64-
targets_.push_back({target_id, type, title, url, worker, attached});
61+
target_manager_->AddTarget(worker, target_id, type, title, url, attached);
6562
}
6663

6764
void TargetAgent::listenWorker(std::weak_ptr<WorkerManager> worker_manager) {
@@ -87,12 +84,26 @@ void TargetAgent::targetCreated(const std::string_view target_id,
8784
frontend_->targetCreated(createTargetInfo(target_id, type, title, url));
8885
}
8986

87+
crdtp::DispatchResponse TargetAgent::getTargets(
88+
std::unique_ptr<protocol::Array<Target::TargetInfo>>* out_targetInfos) {
89+
auto target_infos = std::make_unique<protocol::Array<Target::TargetInfo>>();
90+
for (const auto& target : target_manager_->GetTargetsSnapshot()) {
91+
target_infos->push_back(createTargetInfo(target.target_id,
92+
target.type,
93+
target.title,
94+
target.url,
95+
target.attached));
96+
}
97+
*out_targetInfos = std::move(target_infos);
98+
return DispatchResponse::Success();
99+
}
100+
90101
int TargetAgent::getNextSessionId() {
91-
return next_session_id_++;
102+
return target_manager_->NextSessionId();
92103
}
93104

94105
int TargetAgent::getNextTargetId() {
95-
return next_target_id_++;
106+
return target_manager_->NextTargetId();
96107
}
97108

98109
void TargetAgent::attachedToTarget(std::shared_ptr<MainThreadHandle> worker,
@@ -101,7 +112,7 @@ void TargetAgent::attachedToTarget(std::shared_ptr<MainThreadHandle> worker,
101112
const std::string& title,
102113
const std::string& url) {
103114
int session_id = getNextSessionId();
104-
target_session_id_worker_map_[session_id] = worker;
115+
TargetManager::RegisterSessionWorker(session_id, worker);
105116
worker->SetTargetSessionId(session_id);
106117
frontend_->attachedToTarget(std::to_string(session_id),
107118
createTargetInfo(target_id, type, title, url),
@@ -112,11 +123,10 @@ void TargetAgent::attachedToTarget(std::shared_ptr<MainThreadHandle> worker,
112123
// all threads. Modify it to be managed per worker thread.
113124
crdtp::DispatchResponse TargetAgent::setAutoAttach(
114125
bool auto_attach, bool wait_for_debugger_on_start) {
115-
auto_attach_ = auto_attach;
116-
wait_for_debugger_on_start_ = wait_for_debugger_on_start;
126+
target_manager_->SetAutoAttach(auto_attach, wait_for_debugger_on_start);
117127

118128
if (auto_attach) {
119-
for (auto& target : targets_) {
129+
for (auto& target : target_manager_->targets()) {
120130
if (!target.attached) {
121131
target.attached = true;
122132
attachedToTarget(target.worker,

src/inspector/target_agent.h

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
#ifndef SRC_INSPECTOR_TARGET_AGENT_H_
22
#define SRC_INSPECTOR_TARGET_AGENT_H_
33

4+
#include <memory>
45
#include <string_view>
5-
#include <unordered_map>
6-
#include <vector>
6+
#include "inspector/target_manager.h"
77
#include "inspector/worker_inspector.h"
88
#include "node/inspector/protocol/Target.h"
99

@@ -14,15 +14,6 @@ class TargetInspector;
1414

1515
namespace protocol {
1616

17-
struct TargetInfo {
18-
std::string target_id;
19-
std::string type;
20-
std::string title;
21-
std::string url;
22-
std::shared_ptr<MainThreadHandle> worker;
23-
bool attached;
24-
};
25-
2617
class TargetAgent : public Target::Backend,
2718
public std::enable_shared_from_this<TargetAgent> {
2819
public:
@@ -32,15 +23,14 @@ class TargetAgent : public Target::Backend,
3223
const std::string& title,
3324
const std::string& url);
3425

26+
DispatchResponse getTargets(
27+
std::unique_ptr<protocol::Array<Target::TargetInfo>>* out_targetInfos)
28+
override;
3529
DispatchResponse setAutoAttach(bool auto_attach,
3630
bool wait_for_debugger_on_start) override;
3731

3832
void listenWorker(std::weak_ptr<WorkerManager> worker_manager);
3933
void reset();
40-
static std::unordered_map<int, std::shared_ptr<MainThreadHandle>>
41-
target_session_id_worker_map_;
42-
43-
bool isThisThread(MainThreadHandle* worker) { return worker == main_thread_; }
4434

4535
private:
4636
int getNextTargetId();
@@ -57,15 +47,9 @@ class TargetAgent : public Target::Backend,
5747

5848
std::shared_ptr<Target::Frontend> frontend_;
5949
std::weak_ptr<WorkerManager> worker_manager_;
60-
static int next_session_id_;
61-
int next_target_id_ = 1;
6250
std::unique_ptr<WorkerManagerEventHandle> worker_event_handle_ = nullptr;
63-
bool auto_attach_ = false;
64-
// TODO(islandryu): If false, implement it so that each thread does not wait
65-
// for the worker to execute.
66-
bool wait_for_debugger_on_start_ = true;
67-
std::vector<TargetInfo> targets_;
68-
MainThreadHandle* main_thread_;
51+
std::unique_ptr<TargetManager> target_manager_ =
52+
std::make_unique<TargetManager>();
6953
};
7054

7155
} // namespace protocol

src/inspector/target_manager.cc

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#include "inspector/target_manager.h"
2+
3+
#include "inspector/main_thread_interface.h"
4+
5+
namespace node {
6+
namespace inspector {
7+
8+
Mutex TargetManager::session_state_lock_;
9+
std::unordered_map<int, std::shared_ptr<MainThreadHandle>>
10+
TargetManager::session_worker_map_;
11+
int TargetManager::next_session_id_ = 1;
12+
13+
int TargetManager::NextTargetId() {
14+
return next_target_id_++;
15+
}
16+
17+
int TargetManager::NextSessionId() {
18+
Mutex::ScopedLock scoped_lock(session_state_lock_);
19+
return next_session_id_++;
20+
}
21+
22+
void TargetManager::SetAutoAttach(bool auto_attach,
23+
bool wait_for_debugger_on_start) {
24+
auto_attach_ = auto_attach;
25+
wait_for_debugger_on_start_ = wait_for_debugger_on_start;
26+
}
27+
28+
void TargetManager::AddTarget(std::shared_ptr<MainThreadHandle> worker,
29+
const std::string& target_id,
30+
const std::string& type,
31+
const std::string& title,
32+
const std::string& url,
33+
bool attached) {
34+
targets_.push_back({target_id, type, title, url, worker, attached});
35+
}
36+
37+
std::vector<TargetManager::TargetInfo> TargetManager::GetTargetsSnapshot()
38+
const {
39+
std::vector<TargetInfo> result;
40+
result.reserve(targets_.size());
41+
for (const auto& target : targets_) {
42+
if (target.worker && !target.worker->Expired()) {
43+
result.push_back(target);
44+
}
45+
}
46+
return result;
47+
}
48+
49+
void TargetManager::RegisterSessionWorker(
50+
int session_id, std::shared_ptr<MainThreadHandle> worker) {
51+
Mutex::ScopedLock scoped_lock(session_state_lock_);
52+
session_worker_map_[session_id] = std::move(worker);
53+
}
54+
55+
std::shared_ptr<MainThreadHandle> TargetManager::WorkerForSession(
56+
int session_id) {
57+
Mutex::ScopedLock scoped_lock(session_state_lock_);
58+
auto it = session_worker_map_.find(session_id);
59+
if (it == session_worker_map_.end()) {
60+
return nullptr;
61+
}
62+
return it->second;
63+
}
64+
65+
} // namespace inspector
66+
} // namespace node

src/inspector/target_manager.h

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#ifndef SRC_INSPECTOR_TARGET_MANAGER_H_
2+
#define SRC_INSPECTOR_TARGET_MANAGER_H_
3+
4+
#include <memory>
5+
#include <string>
6+
#include <unordered_map>
7+
#include <vector>
8+
9+
#include "node_mutex.h"
10+
11+
namespace node {
12+
namespace inspector {
13+
14+
class MainThreadHandle;
15+
16+
class TargetManager {
17+
public:
18+
struct TargetInfo {
19+
std::string target_id;
20+
std::string type;
21+
std::string title;
22+
std::string url;
23+
std::shared_ptr<MainThreadHandle> worker;
24+
bool attached;
25+
};
26+
27+
TargetManager() = default;
28+
29+
int NextTargetId();
30+
int NextSessionId();
31+
32+
void SetAutoAttach(bool auto_attach, bool wait_for_debugger_on_start);
33+
bool auto_attach() const { return auto_attach_; }
34+
bool wait_for_debugger_on_start() const {
35+
return wait_for_debugger_on_start_;
36+
}
37+
38+
void AddTarget(std::shared_ptr<MainThreadHandle> worker,
39+
const std::string& target_id,
40+
const std::string& type,
41+
const std::string& title,
42+
const std::string& url,
43+
bool attached);
44+
std::vector<TargetInfo> GetTargetsSnapshot() const;
45+
std::vector<TargetInfo>& targets() { return targets_; }
46+
const std::vector<TargetInfo>& targets() const { return targets_; }
47+
48+
static void RegisterSessionWorker(int session_id,
49+
std::shared_ptr<MainThreadHandle> worker);
50+
static std::shared_ptr<MainThreadHandle> WorkerForSession(int session_id);
51+
52+
private:
53+
static Mutex session_state_lock_;
54+
static std::unordered_map<int, std::shared_ptr<MainThreadHandle>>
55+
session_worker_map_;
56+
static int next_session_id_;
57+
58+
int next_target_id_ = 1;
59+
bool auto_attach_ = false;
60+
// TODO(islandryu): Honor this flag for worker targets. It is stored here
61+
// so Target.setAutoAttach() state can be tracked, but worker startup pause
62+
// behavior does not change based on it yet.
63+
bool wait_for_debugger_on_start_ = true;
64+
std::vector<TargetInfo> targets_;
65+
};
66+
67+
} // namespace inspector
68+
} // namespace node
69+
70+
#endif // SRC_INSPECTOR_TARGET_MANAGER_H_

src/inspector_io.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "inspector/node_json.h"
88
#include "inspector/node_string.h"
99
#include "inspector/target_agent.h"
10+
#include "inspector/target_manager.h"
1011
#include "inspector_socket_server.h"
1112
#include "ncrypto.h"
1213
#include "node.h"
@@ -380,8 +381,7 @@ void InspectorIoDelegate::MessageReceived(int session_id,
380381
::isdigit);
381382
if (is_number) {
382383
int target_session_id = std::stoi(*target_session_id_str);
383-
worker = protocol::TargetAgent::target_session_id_worker_map_
384-
[target_session_id];
384+
worker = TargetManager::WorkerForSession(target_session_id);
385385
if (worker) {
386386
merged_session_id += target_session_id << 16;
387387
}

test/parallel/test-inspector-worker-target.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
const common = require('../common');
44
const fixtures = require('../common/fixtures');
55

6+
const assert = require('assert');
7+
68
common.skipIfInspectorDisabled();
79

810
const { NodeInstance } = require('../common/inspector-helper.js');
@@ -21,6 +23,15 @@ async function setupInspector(session, sessionId = undefined) {
2123
});
2224
}
2325

26+
async function assertTargetAttachedState(session, targetId, attached) {
27+
const { targetInfos } = await session.send({ method: 'Target.getTargets' });
28+
const targetInfo = targetInfos.find((target) => {
29+
return target.targetId === targetId;
30+
});
31+
assert.notStrictEqual(targetInfo, undefined);
32+
assert.strictEqual(targetInfo.attached, attached);
33+
}
34+
2435
async function test(isSetAutoAttachBeforeExecution) {
2536
const child = new NodeInstance(['--inspect-brk=0', '--experimental-worker-inspection'],
2637
'',
@@ -38,7 +49,10 @@ async function test(isSetAutoAttachBeforeExecution) {
3849
await session.send({ method: 'Debugger.resume' });
3950

4051
const sessionId = '1';
41-
await session.waitForNotification('Target.targetCreated');
52+
const targetCreated = await session.waitForNotification('Target.targetCreated');
53+
const targetId = targetCreated.params.targetInfo.targetId;
54+
55+
await assertTargetAttachedState(session, targetId, isSetAutoAttachBeforeExecution);
4256

4357
if (!isSetAutoAttachBeforeExecution) {
4458
await session.send({ method: 'Target.setAutoAttach', params: { autoAttach: true, waitForDebuggerOnStart: true } });
@@ -47,6 +61,7 @@ async function test(isSetAutoAttachBeforeExecution) {
4761
return notification.method === 'Target.attachedToTarget' &&
4862
notification.params.sessionId === sessionId;
4963
});
64+
await assertTargetAttachedState(session, targetId, true);
5065
await setupInspector(session, sessionId);
5166
await session.waitForNotification('Debugger.paused');
5267
await session.send({ method: 'Debugger.resume', sessionId });

0 commit comments

Comments
 (0)