| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1236,6 +1236,17 @@ added: v22.4.0 | |||
| 1236 | 1236 | ||
| 1237 | 1237 | Enable experimental [`Web Storage`][] support. | |
| 1238 | 1238 | ||
| 1239 | + ### `--experimental-worker-inspection` | ||
| 1240 | + | ||
| 1241 | + <!-- YAML | ||
| 1242 | + added: | ||
| 1243 | + - REPLACEME | ||
| 1244 | + --> | ||
| 1245 | + | ||
| 1246 | + > Stability: 1.1 - Active Development | ||
| 1247 | + | ||
| 1248 | + Enable experimental support for the worker inspection with Chrome DevTools. | ||
| 1249 | + | ||
| 1239 | 1250 | ### `--expose-gc` | |
| 1240 | 1251 | ||
| 1241 | 1252 | <!-- YAML | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -57,6 +57,10 @@ class MainThreadHandle : public std::enable_shared_from_this<MainThreadHandle> { | |||
| 57 | 57 | std::unique_ptr<InspectorSessionDelegate> MakeDelegateThreadSafe( | |
| 58 | 58 | std::unique_ptr<InspectorSessionDelegate> delegate); | |
| 59 | 59 | bool Expired(); | |
| 60 | + void SetTargetSessionId(int target_session_id) { | ||
| 61 | + target_session_id_ = target_session_id; | ||
| 62 | + } | ||
| 63 | + std::optional<int> GetTargetSessionId() { return target_session_id_; } | ||
| 60 | 64 | ||
| 61 | 65 | private: | |
| 62 | 66 | void Reset(); | |
@@ -65,6 +69,7 @@ class MainThreadHandle : public std::enable_shared_from_this<MainThreadHandle> { | |||
| 65 | 69 | Mutex block_lock_; | |
| 66 | 70 | int next_session_id_ = 0; | |
| 67 | 71 | std::atomic_int next_object_id_ = {1}; | |
| 72 | + std::optional<int> target_session_id_ = std::nullopt; | ||
| 68 | 73 | ||
| 69 | 74 | friend class MainThreadInterface; | |
| 70 | 75 | }; | |
| 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_agent.cc', | ||
| 36 | + 'src/inspector/target_agent.h', | ||
| 35 | 37 | 'src/inspector/worker_inspector.cc', | |
| 36 | 38 | 'src/inspector/worker_inspector.h', | |
| 37 | 39 | ], | |
@@ -47,6 +49,8 @@ | |||
| 47 | 49 | '<(SHARED_INTERMEDIATE_DIR)/src/node/inspector/protocol/NodeRuntime.h', | |
| 48 | 50 | '<(SHARED_INTERMEDIATE_DIR)/src/node/inspector/protocol/Network.cpp', | |
| 49 | 51 | '<(SHARED_INTERMEDIATE_DIR)/src/node/inspector/protocol/Network.h', | |
| 52 | + '<(SHARED_INTERMEDIATE_DIR)/src/node/inspector/protocol/Target.cpp', | ||
| 53 | + '<(SHARED_INTERMEDIATE_DIR)/src/node/inspector/protocol/Target.h', | ||
| 50 | 54 | ], | |
| 51 | 55 | 'node_protocol_files': [ | |
| 52 | 56 | '<(protocol_tool_path)/lib/Forward_h.template', | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -249,3 +249,28 @@ experimental domain NodeRuntime | |||
| 249 | 249 | # This event is fired when the runtime is waiting for the debugger. For | |
| 250 | 250 | # example, when inspector.waitingForDebugger is called | |
| 251 | 251 | event waitingForDebugger | |
| 252 | + | ||
| 253 | + # https://chromedevtools.github.io/devtools-protocol/1-3/Target/ | ||
| 254 | + experimental domain Target | ||
| 255 | + type SessionID extends string | ||
| 256 | + type TargetID extends string | ||
| 257 | + type TargetInfo extends object | ||
| 258 | + properties | ||
| 259 | + TargetID targetId | ||
| 260 | + string type | ||
| 261 | + string title | ||
| 262 | + string url | ||
| 263 | + boolean attached | ||
| 264 | + boolean canAccessOpener | ||
| 265 | + event targetCreated | ||
| 266 | + parameters | ||
| 267 | + TargetInfo targetInfo | ||
| 268 | + event attachedToTarget | ||
| 269 | + parameters | ||
| 270 | + SessionID sessionId | ||
| 271 | + TargetInfo targetInfo | ||
| 272 | + boolean waitingForDebugger | ||
| 273 | + command setAutoAttach | ||
| 274 | + parameters | ||
| 275 | + boolean autoAttach | ||
| 276 | + boolean waitForDebuggerOnStart | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,136 @@ | |||
| 1 | + #include "target_agent.h" | ||
| 2 | + #include <string_view> | ||
| 3 | + #include "crdtp/dispatch.h" | ||
| 4 | + #include "inspector/worker_inspector.h" | ||
| 5 | + #include "main_thread_interface.h" | ||
| 6 | + | ||
| 7 | + namespace node { | ||
| 8 | + namespace inspector { | ||
| 9 | + namespace protocol { | ||
| 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 | + class WorkerTargetDelegate : public WorkerDelegate { | ||
| 16 | + public: | ||
| 17 | + explicit WorkerTargetDelegate(std::shared_ptr<TargetAgent> target_agent) | ||
| 18 | + : target_agent_(target_agent) {} | ||
| 19 | + | ||
| 20 | + void WorkerCreated(const std::string& title, | ||
| 21 | + const std::string& url, | ||
| 22 | + bool waiting, | ||
| 23 | + std::shared_ptr<MainThreadHandle> worker) override { | ||
| 24 | + target_agent_->createAndAttachIfNecessary(worker, title, url); | ||
| 25 | + } | ||
| 26 | + | ||
| 27 | + private: | ||
| 28 | + const std::shared_ptr<TargetAgent> target_agent_; | ||
| 29 | + }; | ||
| 30 | + | ||
| 31 | + std::unique_ptr<Target::TargetInfo> createTargetInfo( | ||
| 32 | + const std::string_view target_id, | ||
| 33 | + const std::string_view type, | ||
| 34 | + const std::string_view title, | ||
| 35 | + const std::string_view url) { | ||
| 36 | + return Target::TargetInfo::create() | ||
| 37 | + .setTargetId(std::string(target_id)) | ||
| 38 | + .setType(std::string(type)) | ||
| 39 | + .setTitle(std::string(title)) | ||
| 40 | + .setUrl(std::string(url)) | ||
| 41 | + .setAttached(false) | ||
| 42 | + .setCanAccessOpener(true) | ||
| 43 | + .build(); | ||
| 44 | + } | ||
| 45 | + | ||
| 46 | + void TargetAgent::Wire(UberDispatcher* dispatcher) { | ||
| 47 | + frontend_ = std::make_unique<Target::Frontend>(dispatcher->channel()); | ||
| 48 | + Target::Dispatcher::wire(dispatcher, this); | ||
| 49 | + } | ||
| 50 | + | ||
| 51 | + void TargetAgent::createAndAttachIfNecessary( | ||
| 52 | + std::shared_ptr<MainThreadHandle> worker, | ||
| 53 | + const std::string& title, | ||
| 54 | + const std::string& url) { | ||
| 55 | + std::string target_id = std::to_string(getNextTargetId()); | ||
| 56 | + std::string type = "node_worker"; | ||
| 57 | + | ||
| 58 | + targetCreated(target_id, type, title, url); | ||
| 59 | + bool attached = false; | ||
| 60 | + if (auto_attach_) { | ||
| 61 | + attached = true; | ||
| 62 | + attachedToTarget(worker, target_id, type, title, url); | ||
| 63 | + } | ||
| 64 | + targets_.push_back({target_id, type, title, url, worker, attached}); | ||
| 65 | + } | ||
| 66 | + | ||
| 67 | + void TargetAgent::listenWorker(std::weak_ptr<WorkerManager> worker_manager) { | ||
| 68 | + auto manager = worker_manager.lock(); | ||
| 69 | + if (!manager) { | ||
| 70 | + return; | ||
| 71 | + } | ||
| 72 | + std::unique_ptr<WorkerDelegate> delegate( | ||
| 73 | + new WorkerTargetDelegate(shared_from_this())); | ||
| 74 | + worker_event_handle_ = manager->SetAutoAttach(std::move(delegate)); | ||
| 75 | + } | ||
| 76 | + | ||
| 77 | + void TargetAgent::reset() { | ||
| 78 | + if (worker_event_handle_) { | ||
| 79 | + worker_event_handle_.reset(); | ||
| 80 | + } | ||
| 81 | + } | ||
| 82 | + | ||
| 83 | + void TargetAgent::targetCreated(const std::string_view target_id, | ||
| 84 | + const std::string_view type, | ||
| 85 | + const std::string_view title, | ||
| 86 | + const std::string_view url) { | ||
| 87 | + frontend_->targetCreated(createTargetInfo(target_id, type, title, url)); | ||
| 88 | + } | ||
| 89 | + | ||
| 90 | + int TargetAgent::getNextSessionId() { | ||
| 91 | + return next_session_id_++; | ||
| 92 | + } | ||
| 93 | + | ||
| 94 | + int TargetAgent::getNextTargetId() { | ||
| 95 | + return next_target_id_++; | ||
| 96 | + } | ||
| 97 | + | ||
| 98 | + void TargetAgent::attachedToTarget(std::shared_ptr<MainThreadHandle> worker, | ||
| 99 | + const std::string& target_id, | ||
| 100 | + const std::string& type, | ||
| 101 | + const std::string& title, | ||
| 102 | + const std::string& url) { | ||
| 103 | + int session_id = getNextSessionId(); | ||
| 104 | + target_session_id_worker_map_[session_id] = worker; | ||
| 105 | + worker->SetTargetSessionId(session_id); | ||
| 106 | + frontend_->attachedToTarget(std::to_string(session_id), | ||
| 107 | + createTargetInfo(target_id, type, title, url), | ||
| 108 | + true); | ||
| 109 | + } | ||
| 110 | + | ||
| 111 | + // TODO(islandryu): Currently, setAutoAttach applies the main thread's value to | ||
| 112 | + // all threads. Modify it to be managed per worker thread. | ||
| 113 | + crdtp::DispatchResponse TargetAgent::setAutoAttach( | ||
| 114 | + 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; | ||
| 117 | + | ||
| 118 | + if (auto_attach) { | ||
| 119 | + for (auto& target : targets_) { | ||
| 120 | + if (!target.attached) { | ||
| 121 | + target.attached = true; | ||
| 122 | + attachedToTarget(target.worker, | ||
| 123 | + target.target_id, | ||
| 124 | + target.type, | ||
| 125 | + target.title, | ||
| 126 | + target.url); | ||
| 127 | + } | ||
| 128 | + } | ||
| 129 | + } | ||
| 130 | + | ||
| 131 | + return DispatchResponse::Success(); | ||
| 132 | + } | ||
| 133 | + | ||
| 134 | + } // namespace protocol | ||
| 135 | + } // namespace inspector | ||
| 136 | + } // namespace node | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,75 @@ | |||
| 1 | + #ifndef SRC_INSPECTOR_TARGET_AGENT_H_ | ||
| 2 | + #define SRC_INSPECTOR_TARGET_AGENT_H_ | ||
| 3 | + | ||
| 4 | + #include <string_view> | ||
| 5 | + #include <unordered_map> | ||
| 6 | + #include <vector> | ||
| 7 | + #include "inspector/worker_inspector.h" | ||
| 8 | + #include "node/inspector/protocol/Target.h" | ||
| 9 | + | ||
| 10 | + namespace node { | ||
| 11 | + | ||
| 12 | + namespace inspector { | ||
| 13 | + class TargetInspector; | ||
| 14 | + | ||
| 15 | + namespace protocol { | ||
| 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 | + class TargetAgent : public Target::Backend, | ||
| 27 | + public std::enable_shared_from_this<TargetAgent> { | ||
| 28 | + public: | ||
| 29 | + void Wire(UberDispatcher* dispatcher); | ||
| 30 | + | ||
| 31 | + void createAndAttachIfNecessary(std::shared_ptr<MainThreadHandle> worker, | ||
| 32 | + const std::string& title, | ||
| 33 | + const std::string& url); | ||
| 34 | + | ||
| 35 | + DispatchResponse setAutoAttach(bool auto_attach, | ||
| 36 | + bool wait_for_debugger_on_start) override; | ||
| 37 | + | ||
| 38 | + void listenWorker(std::weak_ptr<WorkerManager> worker_manager); | ||
| 39 | + 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 | + | ||
| 45 | + private: | ||
| 46 | + int getNextTargetId(); | ||
| 47 | + int getNextSessionId(); | ||
| 48 | + void targetCreated(const std::string_view target_id, | ||
| 49 | + const std::string_view type, | ||
| 50 | + const std::string_view title, | ||
| 51 | + const std::string_view url); | ||
| 52 | + void attachedToTarget(std::shared_ptr<MainThreadHandle> worker, | ||
| 53 | + const std::string& target_id, | ||
| 54 | + const std::string& type, | ||
| 55 | + const std::string& title, | ||
| 56 | + const std::string& url); | ||
| 57 | + | ||
| 58 | + std::shared_ptr<Target::Frontend> frontend_; | ||
| 59 | + std::weak_ptr<WorkerManager> worker_manager_; | ||
| 60 | + static int next_session_id_; | ||
| 61 | + int next_target_id_ = 1; | ||
| 62 | + 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_; | ||
| 69 | + }; | ||
| 70 | + | ||
| 71 | + } // namespace protocol | ||
| 72 | + } // namespace inspector | ||
| 73 | + } // namespace node | ||
| 74 | + | ||
| 75 | + #endif // SRC_INSPECTOR_TARGET_AGENT_H_ | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments