Skip to content

Commit daafe6c

Browse files
addaleaxtargos
authored andcommitted
src: refactor tracing agent code
Avoid unnecessary operations, add a bit of documentation, and turn the `ClientHandle` smart pointer alias into a real class. This should allow de-coupling the unnecessary combination of a single specific `file_writer` from `Agent`. PR-URL: #21867 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Eugene Ostroukhov <[email protected]> Reviewed-By: Ali Ijaz Sheikh <[email protected]>
1 parent 4379140 commit daafe6c

File tree

5 files changed

+87
-58
lines changed

5 files changed

+87
-58
lines changed

‎src/inspector/tracing_agent.cc‎

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,7 @@ class InspectorTraceWriter : public node::tracing::AsyncTraceWriter{
4646
} // namespace
4747

4848
TracingAgent::TracingAgent(Environment* env)
49-
: env_(env),
50-
trace_writer_(
51-
tracing::Agent::EmptyClientHandle()){
49+
: env_(env){
5250
}
5351

5452
TracingAgent::~TracingAgent(){
@@ -62,7 +60,7 @@ void TracingAgent::Wire(UberDispatcher* dispatcher){
6260

6361
DispatchResponse TracingAgent::start(
6462
std::unique_ptr<protocol::NodeTracing::TraceConfig> traceConfig){
65-
if (trace_writer_ != nullptr){
63+
if (!trace_writer_.empty()){
6664
returnDispatchResponse::Error(
6765
"Call NodeTracing::end to stop tracing before updating the config");
6866
}

‎src/inspector/tracing_agent.h‎

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,13 @@
22
#defineSRC_INSPECTOR_TRACING_AGENT_H_
33

44
#include"node/inspector/protocol/NodeTracing.h"
5+
#include"tracing/agent.h"
56
#include"v8.h"
67

78

89
namespacenode{
910
classEnvironment;
1011

11-
namespacetracing{
12-
classAgent;
13-
} // namespace tracing
14-
1512
namespaceinspector{
1613
namespaceprotocol{
1714

@@ -32,8 +29,7 @@ class TracingAgent : public NodeTracing::Backend{
3229
voidDisconnectTraceClient();
3330

3431
Environment* env_;
35-
std::unique_ptr<std::pair<tracing::Agent*, int>,
36-
void (*)(std::pair<tracing::Agent*, int>*)> trace_writer_;
32+
tracing::AgentWriterHandle trace_writer_;
3733
std::unique_ptr<NodeTracing::Frontend> frontend_;
3834
};
3935

‎src/node.cc‎

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,7 @@ class NodeTraceStateObserver :
387387
staticstruct{
388388
#if NODE_USE_V8_PLATFORM
389389
voidInitialize(int thread_pool_size){
390-
tracing_agent_.reset(newtracing::Agent(trace_file_pattern));
390+
tracing_agent_.reset(newtracing::Agent());
391391
auto controller = tracing_agent_->GetTracingController();
392392
controller->AddTraceStateObserver(newNodeTraceStateObserver(controller));
393393
tracing::TraceEventHelper::SetTracingController(controller);
@@ -427,12 +427,13 @@ static struct{
427427
#endif// HAVE_INSPECTOR
428428

429429
voidStartTracingAgent(){
430-
tracing_agent_->Enable(trace_enabled_categories);
430+
tracing_file_writer_ = tracing_agent_->AddClient(
431+
trace_enabled_categories,
432+
newtracing::NodeTraceWriter(trace_file_pattern));
431433
}
432434

433435
voidStopTracingAgent(){
434-
if (tracing_agent_)
435-
tracing_agent_->Stop();
436+
tracing_file_writer_.reset();
436437
}
437438

438439
tracing::Agent* GetTracingAgent() const{
@@ -444,6 +445,7 @@ static struct{
444445
}
445446

446447
std::unique_ptr<tracing::Agent> tracing_agent_;
448+
tracing::AgentWriterHandle tracing_file_writer_;
447449
NodePlatform* platform_;
448450
#else// !NODE_USE_V8_PLATFORM
449451
voidInitialize(int thread_pool_size){}

‎src/tracing/agent.cc‎

Lines changed: 20 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ using v8::platform::tracing::TraceWriter;
4444
using std::string;
4545

4646
Agent::Agent(const std::string& log_file_pattern)
47-
: log_file_pattern_(log_file_pattern), file_writer_(EmptyClientHandle()){
47+
: log_file_pattern_(log_file_pattern){
4848
tracing_controller_ = newTracingController();
4949
tracing_controller_->Initialize(nullptr);
5050
}
@@ -62,20 +62,23 @@ void Agent::Start(){
6262
// This thread should be created *after* async handles are created
6363
// (within NodeTraceWriter and NodeTraceBuffer constructors).
6464
// Otherwise the thread could shut down prematurely.
65-
CHECK_EQ(0, uv_thread_create(&thread_, ThreadCb, this));
65+
CHECK_EQ(0, uv_thread_create(&thread_, [](void* arg){
66+
Agent* agent = static_cast<Agent*>(arg);
67+
uv_run(&agent->tracing_loop_, UV_RUN_DEFAULT);
68+
}, this));
6669
started_ = true;
6770
}
6871

69-
Agent::ClientHandle Agent::AddClient(const std::set<std::string>& categories,
70-
std::unique_ptr<AsyncTraceWriter> writer){
72+
AgentWriterHandle Agent::AddClient(
73+
const std::set<std::string>& categories,
74+
std::unique_ptr<AsyncTraceWriter> writer){
7175
Start();
7276
ScopedSuspendTracing suspend(tracing_controller_, this);
7377
int id = next_writer_id_++;
7478
writers_[id] = std::move(writer);
7579
categories_[id] = categories;
7680

77-
auto client_id = new std::pair<Agent*, int>(this, id);
78-
returnClientHandle(client_id, &DisconnectClient);
81+
returnAgentWriterHandle(this, id);
7982
}
8083

8184
voidAgent::Stop(){
@@ -101,61 +104,52 @@ void Agent::Disconnect(int client){
101104
categories_.erase(client);
102105
}
103106

104-
// static
105-
voidAgent::ThreadCb(void* arg){
106-
Agent* agent = static_cast<Agent*>(arg);
107-
uv_run(&agent->tracing_loop_, UV_RUN_DEFAULT);
108-
}
109-
110107
voidAgent::Enable(const std::string& categories){
111108
if (categories.empty())
112109
return;
113110
std::set<std::string> categories_set;
114-
std::stringstreamcategory_list(categories);
111+
std::istringstreamcategory_list(categories);
115112
while (category_list.good()){
116113
std::string category;
117114
getline(category_list, category, ',');
118-
categories_set.insert(category);
115+
categories_set.emplace(std::move(category));
119116
}
120117
Enable(categories_set);
121118
}
122119

123120
voidAgent::Enable(const std::set<std::string>& categories){
124-
std::string cats;
125-
for (const std::string cat : categories)
126-
cats += cat + ", ";
127121
if (categories.empty())
128122
return;
129123

130124
file_writer_categories_.insert(categories.begin(), categories.end());
131125
std::set<std::string> full_list(file_writer_categories_.begin(),
132126
file_writer_categories_.end());
133-
if (!file_writer_){
127+
if (file_writer_.empty()){
134128
// Ensure background thread is running
135129
Start();
136130
std::unique_ptr<NodeTraceWriter> writer(
137131
newNodeTraceWriter(log_file_pattern_, &tracing_loop_));
138132
file_writer_ = AddClient(full_list, std::move(writer));
139133
} else{
140134
ScopedSuspendTracing suspend(tracing_controller_, this);
141-
categories_[file_writer_->second] = full_list;
135+
categories_[file_writer_.id_] = full_list;
142136
}
143137
}
144138

145139
voidAgent::Disable(const std::set<std::string>& categories){
146-
for (auto category : categories){
140+
for (const std::string& category : categories){
147141
auto it = file_writer_categories_.find(category);
148142
if (it != file_writer_categories_.end())
149143
file_writer_categories_.erase(it);
150144
}
151-
if (!file_writer_)
145+
if (file_writer_.empty())
152146
return;
153147
ScopedSuspendTracing suspend(tracing_controller_, this);
154-
categories_[file_writer_->second] ={file_writer_categories_.begin(),
155-
file_writer_categories_.end() };
148+
categories_[file_writer_.id_] ={file_writer_categories_.begin(),
149+
file_writer_categories_.end() };
156150
}
157151

158-
TraceConfig* Agent::CreateTraceConfig(){
152+
TraceConfig* Agent::CreateTraceConfig() const{
159153
if (categories_.empty())
160154
returnnullptr;
161155
TraceConfig* trace_config = newTraceConfig();
@@ -165,9 +159,9 @@ TraceConfig* Agent::CreateTraceConfig(){
165159
return trace_config;
166160
}
167161

168-
std::string Agent::GetEnabledCategories(){
162+
std::string Agent::GetEnabledCategories() const{
169163
std::string categories;
170-
for (constauto& category : flatten(categories_)){
164+
for (conststd::string& category : flatten(categories_)){
171165
if (!categories.empty())
172166
categories += ',';
173167
categories += category;

‎src/tracing/agent.h‎

Lines changed: 57 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include"libplatform/v8-tracing.h"
55
#include"uv.h"
66
#include"v8.h"
7+
#include"util.h"
78

89
#include<set>
910
#include<string>
@@ -15,6 +16,8 @@ namespace tracing{
1516
using v8::platform::tracing::TraceConfig;
1617
using v8::platform::tracing::TraceObject;
1718

19+
classAgent;
20+
1821
classAsyncTraceWriter{
1922
public:
2023
virtual~AsyncTraceWriter(){}
@@ -31,42 +34,58 @@ class TracingController : public v8::platform::tracing::TracingController{
3134
}
3235
};
3336

37+
classAgentWriterHandle{
38+
public:
39+
inlineAgentWriterHandle(){}
40+
inline~AgentWriterHandle(){reset()}
41+
42+
inlineAgentWriterHandle(AgentWriterHandle&& other);
43+
inline AgentWriterHandle& operator=(AgentWriterHandle&& other);
44+
inlineboolempty() const{return agent_ == nullptr}
45+
inlinevoidreset();
46+
47+
private:
48+
inlineAgentWriterHandle(Agent* agent, int id) : agent_(agent), id_(id){}
49+
50+
AgentWriterHandle(const AgentWriterHandle& other) = delete;
51+
AgentWriterHandle& operator=(const AgentWriterHandle& other) = delete;
52+
53+
Agent* agent_ = nullptr;
54+
int id_;
55+
56+
friendclassAgent;
57+
};
3458

3559
classAgent{
3660
public:
37-
// Resetting the pointer disconnects client
38-
using ClientHandle = std::unique_ptr<std::pair<Agent*, int>,
39-
void (*)(std::pair<Agent*, int>*)>
40-
41-
static ClientHandle EmptyClientHandle(){
42-
returnClientHandle(nullptr, DisconnectClient);
43-
}
4461
explicitAgent(const std::string& log_file_pattern);
4562
voidStop();
4663

4764
TracingController* GetTracingController(){return tracing_controller_}
4865

4966
// Destroying the handle disconnects the client
50-
ClientHandleAddClient(const std::set<std::string>& categories,
51-
std::unique_ptr<AsyncTraceWriter> writer);
67+
AgentWriterHandleAddClient(const std::set<std::string>& categories,
68+
std::unique_ptr<AsyncTraceWriter> writer);
5269

5370
// These 3 methods operate on a "default" client, e.g. the file writer
5471
voidEnable(const std::string& categories);
5572
voidEnable(const std::set<std::string>& categories);
5673
voidDisable(const std::set<std::string>& categories);
57-
std::string GetEnabledCategories();
5874

75+
// Returns a comma-separated list of enabled categories.
76+
std::string GetEnabledCategories() const;
77+
78+
// Writes to all writers registered through AddClient().
5979
voidAppendTraceEvent(TraceObject* trace_event);
80+
// Flushes all writers registered through AddClient().
6081
voidFlush(bool blocking);
6182

62-
TraceConfig* CreateTraceConfig();
83+
TraceConfig* CreateTraceConfig()const;
6384

6485
private:
86+
friendclassAgentWriterHandle;
87+
6588
staticvoidThreadCb(void* arg);
66-
staticvoidDisconnectClient(std::pair<Agent*, int>* id_agent){
67-
id_agent->first->Disconnect(id_agent->second);
68-
delete id_agent;
69-
}
7089

7190
voidStart();
7291
voidStopTracing();
@@ -77,14 +96,34 @@ class Agent{
7796
uv_loop_t tracing_loop_;
7897
bool started_ = false;
7998

80-
std::unordered_map<int, std::set<std::string>> categories_;
81-
TracingController* tracing_controller_ = nullptr;
82-
ClientHandle file_writer_;
99+
// Each individual Writer has one id.
83100
int next_writer_id_ = 1;
101+
// These maps store the original arguments to AddClient(), by id.
102+
std::unordered_map<int, std::set<std::string>> categories_;
84103
std::unordered_map<int, std::unique_ptr<AsyncTraceWriter>> writers_;
104+
TracingController* tracing_controller_ = nullptr;
105+
AgentWriterHandle file_writer_;
85106
std::multiset<std::string> file_writer_categories_;
86107
};
87108

109+
voidAgentWriterHandle::reset(){
110+
if (agent_ != nullptr)
111+
agent_->Disconnect(id_);
112+
agent_ = nullptr;
113+
}
114+
115+
AgentWriterHandle& AgentWriterHandle::operator=(AgentWriterHandle&& other){
116+
reset();
117+
agent_ = other.agent_;
118+
id_ = other.id_;
119+
other.agent_ = nullptr;
120+
return *this;
121+
}
122+
123+
AgentWriterHandle::AgentWriterHandle(AgentWriterHandle&& other){
124+
*this = std::move(other);
125+
}
126+
88127
} // namespace tracing
89128
} // namespace node
90129

0 commit comments

Comments
(0)