summaryrefslogtreecommitdiff
path: root/src/inspector/worker_agent.cc
diff options
context:
space:
mode:
authorEugene Ostroukhov <eostroukhov@google.com>2018-09-08 19:45:10 -0700
committerEugene Ostroukhov <eostroukhov@google.com>2018-09-18 09:01:33 -0700
commitf28c6f7eef58e7c3133bb2cd457d05b986194ba3 (patch)
treeb8e8583ff735a3b0721831af51c4f92d967849f1 /src/inspector/worker_agent.cc
parentba0b4e43e442926bfb9389a42aa7393f91e6748a (diff)
downloadandroid-node-v8-f28c6f7eef58e7c3133bb2cd457d05b986194ba3.tar.gz
android-node-v8-f28c6f7eef58e7c3133bb2cd457d05b986194ba3.tar.bz2
android-node-v8-f28c6f7eef58e7c3133bb2cd457d05b986194ba3.zip
inspector: workers debugging
Introduce a NodeTarget inspector domain modelled after ChromeDevTools Target domain. It notifies inspector frontend attached to a main V8 isolate when workers are starting and allows passing messages to inspectors on their isolates. All inspector functionality is enabled on worker isolates. PR-URL: https://github.com/nodejs/node/pull/21364 Reviewed-By: Aleksei Koziatinskii <ak239spb@gmail.com> Reviewed-By: Jan Krems <jan.krems@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net>
Diffstat (limited to 'src/inspector/worker_agent.cc')
-rw-r--r--src/inspector/worker_agent.cc154
1 files changed, 154 insertions, 0 deletions
diff --git a/src/inspector/worker_agent.cc b/src/inspector/worker_agent.cc
new file mode 100644
index 0000000000..fccd6d57a5
--- /dev/null
+++ b/src/inspector/worker_agent.cc
@@ -0,0 +1,154 @@
+#include "worker_agent.h"
+
+#include "main_thread_interface.h"
+#include "worker_inspector.h"
+
+namespace node {
+namespace inspector {
+namespace protocol {
+
+class NodeWorkers
+ : public std::enable_shared_from_this<NodeWorkers> {
+ public:
+ explicit NodeWorkers(std::weak_ptr<NodeWorker::Frontend> frontend,
+ std::shared_ptr<MainThreadHandle> thread)
+ : frontend_(frontend), thread_(thread) {}
+ void WorkerCreated(const std::string& title,
+ const std::string& url,
+ bool waiting,
+ std::shared_ptr<MainThreadHandle> target);
+ void Receive(const std::string& id, const std::string& message);
+ void Send(const std::string& id, const std::string& message);
+ void Detached(const std::string& id);
+
+ private:
+ std::weak_ptr<NodeWorker::Frontend> frontend_;
+ std::shared_ptr<MainThreadHandle> thread_;
+ std::unordered_map<std::string, std::unique_ptr<InspectorSession>> sessions_;
+ int next_target_id_ = 0;
+};
+
+namespace {
+class AgentWorkerInspectorDelegate : public WorkerDelegate {
+ public:
+ explicit AgentWorkerInspectorDelegate(std::shared_ptr<NodeWorkers> workers)
+ : workers_(workers) {}
+
+ void WorkerCreated(const std::string& title,
+ const std::string& url,
+ bool waiting,
+ std::shared_ptr<MainThreadHandle> target) override {
+ workers_->WorkerCreated(title, url, waiting, target);
+ }
+
+ private:
+ std::shared_ptr<NodeWorkers> workers_;
+};
+
+class ParentInspectorSessionDelegate : public InspectorSessionDelegate {
+ public:
+ ParentInspectorSessionDelegate(const std::string& id,
+ std::shared_ptr<NodeWorkers> workers)
+ : id_(id), workers_(workers) {}
+
+ ~ParentInspectorSessionDelegate() override {
+ workers_->Detached(id_);
+ }
+
+ void SendMessageToFrontend(const v8_inspector::StringView& msg) override {
+ std::string message = protocol::StringUtil::StringViewToUtf8(msg);
+ workers_->Send(id_, message);
+ }
+
+ private:
+ std::string id_;
+ std::shared_ptr<NodeWorkers> workers_;
+};
+
+std::unique_ptr<NodeWorker::WorkerInfo> WorkerInfo(const std::string& id,
+ const std::string& title,
+ const std::string& url) {
+ return NodeWorker::WorkerInfo::create()
+ .setWorkerId(id)
+ .setTitle(title)
+ .setUrl(url)
+ .setType("worker").build();
+}
+} // namespace
+
+WorkerAgent::WorkerAgent(std::weak_ptr<WorkerManager> manager)
+ : manager_(manager) {}
+
+
+void WorkerAgent::Wire(UberDispatcher* dispatcher) {
+ frontend_.reset(new NodeWorker::Frontend(dispatcher->channel()));
+ NodeWorker::Dispatcher::wire(dispatcher, this);
+ auto manager = manager_.lock();
+ CHECK_NOT_NULL(manager);
+ workers_ =
+ std::make_shared<NodeWorkers>(frontend_, manager->MainThread());
+}
+
+DispatchResponse WorkerAgent::sendMessageToWorker(const String& message,
+ const String& sessionId) {
+ workers_->Receive(sessionId, message);
+ return DispatchResponse::OK();
+}
+
+DispatchResponse WorkerAgent::enable(bool waitForDebuggerOnStart) {
+ auto manager = manager_.lock();
+ if (!manager) {
+ return DispatchResponse::OK();
+ }
+ if (!event_handle_) {
+ std::unique_ptr<AgentWorkerInspectorDelegate> delegate(
+ new AgentWorkerInspectorDelegate(workers_));
+ event_handle_ = manager->SetAutoAttach(std::move(delegate));
+ }
+ event_handle_->SetWaitOnStart(waitForDebuggerOnStart);
+ return DispatchResponse::OK();
+}
+
+DispatchResponse WorkerAgent::disable() {
+ event_handle_.reset();
+ return DispatchResponse::OK();
+}
+
+void NodeWorkers::WorkerCreated(const std::string& title,
+ const std::string& url,
+ bool waiting,
+ std::shared_ptr<MainThreadHandle> target) {
+ auto frontend = frontend_.lock();
+ if (!frontend)
+ return;
+ std::string id = std::to_string(++next_target_id_);
+ auto delegate = thread_->MakeDelegateThreadSafe(
+ std::unique_ptr<InspectorSessionDelegate>(
+ new ParentInspectorSessionDelegate(id, shared_from_this())));
+ sessions_[id] = target->Connect(std::move(delegate), true);
+ frontend->attachedToWorker(id, WorkerInfo(id, title, url), waiting);
+}
+
+void NodeWorkers::Send(const std::string& id, const std::string& message) {
+ auto frontend = frontend_.lock();
+ if (frontend)
+ frontend->receivedMessageFromWorker(id, message);
+}
+
+void NodeWorkers::Receive(const std::string& id, const std::string& message) {
+ auto it = sessions_.find(id);
+ if (it != sessions_.end())
+ it->second->Dispatch(Utf8ToStringView(message)->string());
+}
+
+void NodeWorkers::Detached(const std::string& id) {
+ if (sessions_.erase(id) == 0)
+ return;
+ auto frontend = frontend_.lock();
+ if (frontend) {
+ frontend->detachedFromWorker(id);
+ }
+}
+} // namespace protocol
+} // namespace inspector
+} // namespace node