| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -20,6 +20,9 @@ experimental domain Target | |||
| 20 | 20 | SessionID sessionId | |
| 21 | 21 | TargetInfo targetInfo | |
| 22 | 22 | boolean waitingForDebugger | |
| 23 | + command getTargets | ||
| 24 | + returns | ||
| 25 | + array of TargetInfo targetInfos | ||
| 23 | 26 | command setAutoAttach | |
| 24 | 27 | parameters | |
| 25 | 28 | boolean autoAttach | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -32,6 +32,8 @@ | |||
| 32 | 32 | 'src/inspector/network_inspector.h', | |
| 33 | 33 | 'src/inspector/network_agent.cc', | |
| 34 | 34 | 'src/inspector/network_agent.h', | |
| 35 | + 'src/inspector/target_manager.cc', | ||
| 36 | + 'src/inspector/target_manager.h', | ||
| 35 | 37 | 'src/inspector/target_agent.cc', | |
| 36 | 38 | 'src/inspector/target_agent.h', | |
| 37 | 39 | 'src/inspector/worker_inspector.cc', | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -8,10 +8,6 @@ namespace node { | |||
| 8 | 8 | namespace inspector { | |
| 9 | 9 | namespace protocol { | |
| 10 | 10 | ||
| 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; | ||
| 15 | 11 | class WorkerTargetDelegate : public WorkerDelegate { | |
| 16 | 12 | public: | |
| 17 | 13 | explicit WorkerTargetDelegate(std::shared_ptr<TargetAgent> target_agent) | |
@@ -32,13 +28,14 @@ std::unique_ptr<Target::TargetInfo> createTargetInfo( | |||
| 32 | 28 | const std::string_view target_id, | |
| 33 | 29 | const std::string_view type, | |
| 34 | 30 | const std::string_view title, | |
| 35 | - const std::string_view url) { | ||
| 31 | + const std::string_view url, | ||
| 32 | + bool attached = false) { | ||
| 36 | 33 | return Target::TargetInfo::create() | |
| 37 | 34 | .setTargetId(std::string(target_id)) | |
| 38 | 35 | .setType(std::string(type)) | |
| 39 | 36 | .setTitle(std::string(title)) | |
| 40 | 37 | .setUrl(std::string(url)) | |
| 41 | - .setAttached(false) | ||
| 38 | + .setAttached(attached) | ||
| 42 | 39 | .setCanAccessOpener(true) | |
| 43 | 40 | .build(); | |
| 44 | 41 | } | |
@@ -57,11 +54,11 @@ void TargetAgent::createAndAttachIfNecessary( | |||
| 57 | 54 | ||
| 58 | 55 | targetCreated(target_id, type, title, url); | |
| 59 | 56 | bool attached = false; | |
| 60 | - if (auto_attach_) { | ||
| 57 | + if (target_manager_->auto_attach()) { | ||
| 61 | 58 | attached = true; | |
| 62 | 59 | attachedToTarget(worker, target_id, type, title, url); | |
| 63 | 60 | } | |
| 64 | - targets_.push_back({target_id, type, title, url, worker, attached}); | ||
| 61 | + target_manager_->AddTarget(worker, target_id, type, title, url, attached); | ||
| 65 | 62 | } | |
| 66 | 63 | ||
| 67 | 64 | void TargetAgent::listenWorker(std::weak_ptr<WorkerManager> worker_manager) { | |
@@ -87,12 +84,26 @@ void TargetAgent::targetCreated(const std::string_view target_id, | |||
| 87 | 84 | frontend_->targetCreated(createTargetInfo(target_id, type, title, url)); | |
| 88 | 85 | } | |
| 89 | 86 | ||
| 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 | + | ||
| 90 | 101 | int TargetAgent::getNextSessionId() { | |
| 91 | - return next_session_id_++; | ||
| 102 | + return target_manager_->NextSessionId(); | ||
| 92 | 103 | } | |
| 93 | 104 | ||
| 94 | 105 | int TargetAgent::getNextTargetId() { | |
| 95 | - return next_target_id_++; | ||
| 106 | + return target_manager_->NextTargetId(); | ||
| 96 | 107 | } | |
| 97 | 108 | ||
| 98 | 109 | void TargetAgent::attachedToTarget(std::shared_ptr<MainThreadHandle> worker, | |
@@ -101,7 +112,7 @@ void TargetAgent::attachedToTarget(std::shared_ptr<MainThreadHandle> worker, | |||
| 101 | 112 | const std::string& title, | |
| 102 | 113 | const std::string& url) { | |
| 103 | 114 | int session_id = getNextSessionId(); | |
| 104 | - target_session_id_worker_map_[session_id] = worker; | ||
| 115 | + TargetManager::RegisterSessionWorker(session_id, worker); | ||
| 105 | 116 | worker->SetTargetSessionId(session_id); | |
| 106 | 117 | frontend_->attachedToTarget(std::to_string(session_id), | |
| 107 | 118 | createTargetInfo(target_id, type, title, url), | |
@@ -112,11 +123,10 @@ void TargetAgent::attachedToTarget(std::shared_ptr<MainThreadHandle> worker, | |||
| 112 | 123 | // all threads. Modify it to be managed per worker thread. | |
| 113 | 124 | crdtp::DispatchResponse TargetAgent::setAutoAttach( | |
| 114 | 125 | 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); | ||
| 117 | 127 | ||
| 118 | 128 | if (auto_attach) { | |
| 119 | - for (auto& target : targets_) { | ||
| 129 | + for (auto& target : target_manager_->targets()) { | ||
| 120 | 130 | if (!target.attached) { | |
| 121 | 131 | target.attached = true; | |
| 122 | 132 | attachedToTarget(target.worker, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,9 +1,9 @@ | |||
| 1 | 1 | #ifndef SRC_INSPECTOR_TARGET_AGENT_H_ | |
| 2 | 2 | #define SRC_INSPECTOR_TARGET_AGENT_H_ | |
| 3 | 3 | ||
| 4 | + #include <memory> | ||
| 4 | 5 | #include <string_view> | |
| 5 | - #include <unordered_map> | ||
| 6 | - #include <vector> | ||
| 6 | + #include "inspector/target_manager.h" | ||
| 7 | 7 | #include "inspector/worker_inspector.h" | |
| 8 | 8 | #include "node/inspector/protocol/Target.h" | |
| 9 | 9 | ||
@@ -14,15 +14,6 @@ class TargetInspector; | |||
| 14 | 14 | ||
| 15 | 15 | namespace protocol { | |
| 16 | 16 | ||
| 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 | - | ||
| 26 | 17 | class TargetAgent : public Target::Backend, | |
| 27 | 18 | public std::enable_shared_from_this<TargetAgent> { | |
| 28 | 19 | public: | |
@@ -32,15 +23,14 @@ class TargetAgent : public Target::Backend, | |||
| 32 | 23 | const std::string& title, | |
| 33 | 24 | const std::string& url); | |
| 34 | 25 | ||
| 26 | + DispatchResponse getTargets( | ||
| 27 | + std::unique_ptr<protocol::Array<Target::TargetInfo>>* out_targetInfos) | ||
| 28 | + override; | ||
| 35 | 29 | DispatchResponse setAutoAttach(bool auto_attach, | |
| 36 | 30 | bool wait_for_debugger_on_start) override; | |
| 37 | 31 | ||
| 38 | 32 | void listenWorker(std::weak_ptr<WorkerManager> worker_manager); | |
| 39 | 33 | 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_; } | ||
| 44 | 34 | ||
| 45 | 35 | private: | |
| 46 | 36 | int getNextTargetId(); | |
@@ -57,15 +47,9 @@ class TargetAgent : public Target::Backend, | |||
| 57 | 47 | ||
| 58 | 48 | std::shared_ptr<Target::Frontend> frontend_; | |
| 59 | 49 | std::weak_ptr<WorkerManager> worker_manager_; | |
| 60 | - static int next_session_id_; | ||
| 61 | - int next_target_id_ = 1; | ||
| 62 | 50 | 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>(); | ||
| 69 | 53 | }; | |
| 70 | 54 | ||
| 71 | 55 | } // namespace protocol | |
| Original file line number | Diff line number | Diff 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 | ||
| Original file line number | Diff line number | Diff 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_ | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -7,6 +7,7 @@ | |||
| 7 | 7 | #include "inspector/node_json.h" | |
| 8 | 8 | #include "inspector/node_string.h" | |
| 9 | 9 | #include "inspector/target_agent.h" | |
| 10 | + #include "inspector/target_manager.h" | ||
| 10 | 11 | #include "inspector_socket_server.h" | |
| 11 | 12 | #include "ncrypto.h" | |
| 12 | 13 | #include "node.h" | |
@@ -380,8 +381,7 @@ void InspectorIoDelegate::MessageReceived(int session_id, | |||
| 380 | 381 | ::isdigit); | |
| 381 | 382 | if (is_number) { | |
| 382 | 383 | 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); | ||
| 385 | 385 | if (worker) { | |
| 386 | 386 | merged_session_id += target_session_id << 16; | |
| 387 | 387 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -3,6 +3,8 @@ | |||
| 3 | 3 | const common = require('../common'); | |
| 4 | 4 | const fixtures = require('../common/fixtures'); | |
| 5 | 5 | ||
| 6 | + const assert = require('assert'); | ||
| 7 | + | ||
| 6 | 8 | common.skipIfInspectorDisabled(); | |
| 7 | 9 | ||
| 8 | 10 | const { NodeInstance } = require('../common/inspector-helper.js'); | |
@@ -21,6 +23,15 @@ async function setupInspector(session, sessionId = undefined) { | |||
| 21 | 23 | }); | |
| 22 | 24 | } | |
| 23 | 25 | ||
| 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 | + | ||
| 24 | 35 | async function test(isSetAutoAttachBeforeExecution) { | |
| 25 | 36 | const child = new NodeInstance(['--inspect-brk=0', '--experimental-worker-inspection'], | |
| 26 | 37 | '', | |
@@ -38,7 +49,10 @@ async function test(isSetAutoAttachBeforeExecution) { | |||
| 38 | 49 | await session.send({ method: 'Debugger.resume' }); | |
| 39 | 50 | ||
| 40 | 51 | 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); | ||
| 42 | 56 | ||
| 43 | 57 | if (!isSetAutoAttachBeforeExecution) { | |
| 44 | 58 | await session.send({ method: 'Target.setAutoAttach', params: { autoAttach: true, waitForDebuggerOnStart: true } }); | |
@@ -47,6 +61,7 @@ async function test(isSetAutoAttachBeforeExecution) { | |||
| 47 | 61 | return notification.method === 'Target.attachedToTarget' && | |
| 48 | 62 | notification.params.sessionId === sessionId; | |
| 49 | 63 | }); | |
| 64 | + await assertTargetAttachedState(session, targetId, true); | ||
| 50 | 65 | await setupInspector(session, sessionId); | |
| 51 | 66 | await session.waitForNotification('Debugger.paused'); | |
| 52 | 67 | await session.send({ method: 'Debugger.resume', sessionId }); | |
| Back | FazBrowse Home | New Git URL |
0 commit comments