|  | 
|  | 1 | +#include "worker_agent.h" | 
|  | 2 | + | 
|  | 3 | +#include "main_thread_interface.h" | 
|  | 4 | +#include "worker_inspector.h" | 
|  | 5 | + | 
|  | 6 | +namespace node { | 
|  | 7 | +namespace inspector { | 
|  | 8 | +namespace protocol { | 
|  | 9 | + | 
|  | 10 | +class NodeWorkers | 
|  | 11 | +    : public std::enable_shared_from_this<NodeWorkers> { | 
|  | 12 | + public: | 
|  | 13 | +  explicit NodeWorkers(std::weak_ptr<NodeWorker::Frontend> frontend, | 
|  | 14 | +                      std::shared_ptr<MainThreadHandle> thread) | 
|  | 15 | +                      : frontend_(frontend), thread_(thread) {} | 
|  | 16 | +  void WorkerCreated(const std::string& title, | 
|  | 17 | +                     const std::string& url, | 
|  | 18 | +                     bool waiting, | 
|  | 19 | +                     std::shared_ptr<MainThreadHandle> target); | 
|  | 20 | +  void Receive(const std::string& id, const std::string& message); | 
|  | 21 | +  void Send(const std::string& id, const std::string& message); | 
|  | 22 | +  void Detached(const std::string& id); | 
|  | 23 | + | 
|  | 24 | + private: | 
|  | 25 | +  std::weak_ptr<NodeWorker::Frontend> frontend_; | 
|  | 26 | +  std::shared_ptr<MainThreadHandle> thread_; | 
|  | 27 | +  std::unordered_map<std::string, std::unique_ptr<InspectorSession>> sessions_; | 
|  | 28 | +  int next_target_id_ = 0; | 
|  | 29 | +}; | 
|  | 30 | + | 
|  | 31 | +namespace { | 
|  | 32 | +class AgentWorkerInspectorDelegate : public WorkerDelegate { | 
|  | 33 | + public: | 
|  | 34 | +  explicit AgentWorkerInspectorDelegate(std::shared_ptr<NodeWorkers> workers) | 
|  | 35 | +                                        : workers_(workers) {} | 
|  | 36 | + | 
|  | 37 | +  void WorkerCreated(const std::string& title, | 
|  | 38 | +                     const std::string& url, | 
|  | 39 | +                     bool waiting, | 
|  | 40 | +                     std::shared_ptr<MainThreadHandle> target) override { | 
|  | 41 | +    workers_->WorkerCreated(title, url, waiting, target); | 
|  | 42 | +  } | 
|  | 43 | + | 
|  | 44 | + private: | 
|  | 45 | +  std::shared_ptr<NodeWorkers> workers_; | 
|  | 46 | +}; | 
|  | 47 | + | 
|  | 48 | +class ParentInspectorSessionDelegate : public InspectorSessionDelegate { | 
|  | 49 | + public: | 
|  | 50 | +  ParentInspectorSessionDelegate(const std::string& id, | 
|  | 51 | +                                 std::shared_ptr<NodeWorkers> workers) | 
|  | 52 | +                                 : id_(id), workers_(workers) {} | 
|  | 53 | + | 
|  | 54 | +  ~ParentInspectorSessionDelegate() override { | 
|  | 55 | +    workers_->Detached(id_); | 
|  | 56 | +  } | 
|  | 57 | + | 
|  | 58 | +  void SendMessageToFrontend(const v8_inspector::StringView& msg) override { | 
|  | 59 | +    std::string message = protocol::StringUtil::StringViewToUtf8(msg); | 
|  | 60 | +    workers_->Send(id_, message); | 
|  | 61 | +  } | 
|  | 62 | + | 
|  | 63 | + private: | 
|  | 64 | +  std::string id_; | 
|  | 65 | +  std::shared_ptr<NodeWorkers> workers_; | 
|  | 66 | +}; | 
|  | 67 | + | 
|  | 68 | +std::unique_ptr<NodeWorker::WorkerInfo> WorkerInfo(const std::string& id, | 
|  | 69 | +                                                   const std::string& title, | 
|  | 70 | +                                                   const std::string& url) { | 
|  | 71 | +  return NodeWorker::WorkerInfo::create() | 
|  | 72 | +      .setWorkerId(id) | 
|  | 73 | +      .setTitle(title) | 
|  | 74 | +      .setUrl(url) | 
|  | 75 | +      .setType("worker").build(); | 
|  | 76 | +} | 
|  | 77 | +}  // namespace | 
|  | 78 | + | 
|  | 79 | +WorkerAgent::WorkerAgent(std::weak_ptr<WorkerManager> manager) | 
|  | 80 | +                         : manager_(manager) {} | 
|  | 81 | + | 
|  | 82 | + | 
|  | 83 | +void WorkerAgent::Wire(UberDispatcher* dispatcher) { | 
|  | 84 | +  frontend_.reset(new NodeWorker::Frontend(dispatcher->channel())); | 
|  | 85 | +  NodeWorker::Dispatcher::wire(dispatcher, this); | 
|  | 86 | +  auto manager = manager_.lock(); | 
|  | 87 | +  CHECK_NOT_NULL(manager); | 
|  | 88 | +  workers_ = | 
|  | 89 | +      std::make_shared<NodeWorkers>(frontend_, manager->MainThread()); | 
|  | 90 | +} | 
|  | 91 | + | 
|  | 92 | +DispatchResponse WorkerAgent::sendMessageToWorker(const String& message, | 
|  | 93 | +                                                  const String& sessionId) { | 
|  | 94 | +  workers_->Receive(sessionId, message); | 
|  | 95 | +  return DispatchResponse::OK(); | 
|  | 96 | +} | 
|  | 97 | + | 
|  | 98 | +DispatchResponse WorkerAgent::enable(bool waitForDebuggerOnStart) { | 
|  | 99 | +  auto manager = manager_.lock(); | 
|  | 100 | +  if (!manager) { | 
|  | 101 | +    return DispatchResponse::OK(); | 
|  | 102 | +  } | 
|  | 103 | +  if (!event_handle_) { | 
|  | 104 | +    std::unique_ptr<AgentWorkerInspectorDelegate> delegate( | 
|  | 105 | +            new AgentWorkerInspectorDelegate(workers_)); | 
|  | 106 | +    event_handle_ = manager->SetAutoAttach(std::move(delegate)); | 
|  | 107 | +  } | 
|  | 108 | +  event_handle_->SetWaitOnStart(waitForDebuggerOnStart); | 
|  | 109 | +  return DispatchResponse::OK(); | 
|  | 110 | +} | 
|  | 111 | + | 
|  | 112 | +DispatchResponse WorkerAgent::disable() { | 
|  | 113 | +  event_handle_.reset(); | 
|  | 114 | +  return DispatchResponse::OK(); | 
|  | 115 | +} | 
|  | 116 | + | 
|  | 117 | +void NodeWorkers::WorkerCreated(const std::string& title, | 
|  | 118 | +                                const std::string& url, | 
|  | 119 | +                                bool waiting, | 
|  | 120 | +                                std::shared_ptr<MainThreadHandle> target) { | 
|  | 121 | +  auto frontend = frontend_.lock(); | 
|  | 122 | +  if (!frontend) | 
|  | 123 | +    return; | 
|  | 124 | +  std::string id = std::to_string(++next_target_id_); | 
|  | 125 | +  auto delegate = thread_->MakeDelegateThreadSafe( | 
|  | 126 | +      std::unique_ptr<InspectorSessionDelegate>( | 
|  | 127 | +          new ParentInspectorSessionDelegate(id, shared_from_this()))); | 
|  | 128 | +  sessions_[id] = target->Connect(std::move(delegate), true); | 
|  | 129 | +  frontend->attachedToWorker(id, WorkerInfo(id, title, url), waiting); | 
|  | 130 | +} | 
|  | 131 | + | 
|  | 132 | +void NodeWorkers::Send(const std::string& id, const std::string& message) { | 
|  | 133 | +  auto frontend = frontend_.lock(); | 
|  | 134 | +  if (frontend) | 
|  | 135 | +    frontend->receivedMessageFromWorker(id, message); | 
|  | 136 | +} | 
|  | 137 | + | 
|  | 138 | +void NodeWorkers::Receive(const std::string& id, const std::string& message) { | 
|  | 139 | +  auto it = sessions_.find(id); | 
|  | 140 | +  if (it != sessions_.end()) | 
|  | 141 | +    it->second->Dispatch(Utf8ToStringView(message)->string()); | 
|  | 142 | +} | 
|  | 143 | + | 
|  | 144 | +void NodeWorkers::Detached(const std::string& id) { | 
|  | 145 | +  if (sessions_.erase(id) == 0) | 
|  | 146 | +    return; | 
|  | 147 | +  auto frontend = frontend_.lock(); | 
|  | 148 | +  if (frontend) { | 
|  | 149 | +    frontend->detachedFromWorker(id); | 
|  | 150 | +  } | 
|  | 151 | +} | 
|  | 152 | +}  // namespace protocol | 
|  | 153 | +}  // namespace inspector | 
|  | 154 | +}  // namespace node | 
0 commit comments