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