-
Notifications
You must be signed in to change notification settings - Fork 30k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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. Backport-PR-URL: #22954 PR-URL: #21364 Reviewed-By: Aleksei Koziatinskii <ak239spb@gmail.com> Reviewed-By: Jan Krems <jan.krems@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net>
- Loading branch information
Showing
11 changed files
with
775 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
#ifndef SRC_INSPECTOR_WORKER_AGENT_H_ | ||
#define SRC_INSPECTOR_WORKER_AGENT_H_ | ||
|
||
#include "node/inspector/protocol/NodeWorker.h" | ||
#include "v8.h" | ||
|
||
|
||
namespace node { | ||
namespace inspector { | ||
class WorkerManagerEventHandle; | ||
class WorkerManager; | ||
|
||
namespace protocol { | ||
class NodeWorkers; | ||
|
||
class WorkerAgent : public NodeWorker::Backend { | ||
public: | ||
explicit WorkerAgent(std::weak_ptr<WorkerManager> manager); | ||
~WorkerAgent() override = default; | ||
|
||
void Wire(UberDispatcher* dispatcher); | ||
|
||
DispatchResponse sendMessageToWorker(const String& message, | ||
const String& sessionId) override; | ||
|
||
DispatchResponse enable(bool waitForDebuggerOnStart) override; | ||
DispatchResponse disable() override; | ||
|
||
private: | ||
std::shared_ptr<NodeWorker::Frontend> frontend_; | ||
std::weak_ptr<WorkerManager> manager_; | ||
std::unique_ptr<WorkerManagerEventHandle> event_handle_; | ||
std::shared_ptr<NodeWorkers> workers_; | ||
}; | ||
} // namespace protocol | ||
} // namespace inspector | ||
} // namespace node | ||
|
||
#endif // SRC_INSPECTOR_WORKER_AGENT_H_ |
Oops, something went wrong.