Skip to content

Commit c101b39

Browse files
addaleaxtargos
authored andcommitted
src: refactor default trace writer out of agent
The agent code is supposed to manage multiple writers/clients. Adding the default writer into the mix breaks that encapsulation. Instead, manage default options through a separate "virtual" default client handle, and keep the file writer management all to the actual users. 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 daafe6c commit c101b39

File tree

10 files changed

+130
-87
lines changed

10 files changed

+130
-87
lines changed

src/env-inl.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -333,8 +333,8 @@ inline v8::Isolate* Environment::isolate() const {
333333
return isolate_;
334334
}
335335

336-
inline tracing::Agent* Environment::tracing_agent() const {
337-
return tracing_agent_;
336+
inline tracing::AgentWriterHandle* Environment::tracing_agent_writer() const {
337+
return tracing_agent_writer_;
338338
}
339339

340340
inline Environment* Environment::from_immediate_check_handle(

src/env.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,10 @@ void InitThreadLocalOnce() {
103103

104104
Environment::Environment(IsolateData* isolate_data,
105105
Local<Context> context,
106-
tracing::Agent* tracing_agent)
106+
tracing::AgentWriterHandle* tracing_agent_writer)
107107
: isolate_(context->GetIsolate()),
108108
isolate_data_(isolate_data),
109-
tracing_agent_(tracing_agent),
109+
tracing_agent_writer_(tracing_agent_writer),
110110
immediate_info_(context->GetIsolate()),
111111
tick_info_(context->GetIsolate()),
112112
timer_base_(uv_now(isolate_data->event_loop())),

src/env.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ class performance_state;
5555
}
5656

5757
namespace tracing {
58-
class Agent;
58+
class AgentWriterHandle;
5959
}
6060

6161
namespace worker {
@@ -590,7 +590,7 @@ class Environment {
590590

591591
Environment(IsolateData* isolate_data,
592592
v8::Local<v8::Context> context,
593-
tracing::Agent* tracing_agent);
593+
tracing::AgentWriterHandle* tracing_agent_writer);
594594
~Environment();
595595

596596
void Start(int argc,
@@ -628,7 +628,7 @@ class Environment {
628628
inline bool profiler_idle_notifier_started() const;
629629

630630
inline v8::Isolate* isolate() const;
631-
inline tracing::Agent* tracing_agent() const;
631+
inline tracing::AgentWriterHandle* tracing_agent_writer() const;
632632
inline uv_loop_t* event_loop() const;
633633
inline uint32_t watched_providers() const;
634634

@@ -877,7 +877,7 @@ class Environment {
877877

878878
v8::Isolate* const isolate_;
879879
IsolateData* const isolate_data_;
880-
tracing::Agent* const tracing_agent_;
880+
tracing::AgentWriterHandle* const tracing_agent_writer_;
881881
uv_check_t immediate_check_handle_;
882882
uv_idle_t immediate_idle_handle_;
883883
uv_prepare_t idle_prepare_handle_;

src/inspector/tracing_agent.cc

+3-2
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,11 @@ DispatchResponse TracingAgent::start(
7474
if (categories_set.empty())
7575
return DispatchResponse::Error("At least one category should be enabled");
7676

77-
trace_writer_ = env_->tracing_agent()->AddClient(
77+
trace_writer_ = env_->tracing_agent_writer()->agent()->AddClient(
7878
categories_set,
7979
std::unique_ptr<InspectorTraceWriter>(
80-
new InspectorTraceWriter(frontend_.get())));
80+
new InspectorTraceWriter(frontend_.get())),
81+
tracing::Agent::kIgnoreDefaultCategories);
8182
return DispatchResponse::OK();
8283
}
8384

src/node.cc

+18-8
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
#include "req_wrap-inl.h"
6262
#include "string_bytes.h"
6363
#include "tracing/agent.h"
64+
#include "tracing/node_trace_writer.h"
6465
#include "util.h"
6566
#include "uv.h"
6667
#if NODE_USE_V8_PLATFORM
@@ -427,17 +428,24 @@ static struct {
427428
#endif // HAVE_INSPECTOR
428429

429430
void StartTracingAgent() {
430-
tracing_file_writer_ = tracing_agent_->AddClient(
431-
trace_enabled_categories,
432-
new tracing::NodeTraceWriter(trace_file_pattern));
431+
if (trace_enabled_categories.empty()) {
432+
tracing_file_writer_ = tracing_agent_->DefaultHandle();
433+
} else {
434+
tracing_file_writer_ = tracing_agent_->AddClient(
435+
ParseCommaSeparatedSet(trace_enabled_categories),
436+
std::unique_ptr<tracing::AsyncTraceWriter>(
437+
new tracing::NodeTraceWriter(trace_file_pattern,
438+
tracing_agent_->loop())),
439+
tracing::Agent::kUseDefaultCategories);
440+
}
433441
}
434442

435443
void StopTracingAgent() {
436444
tracing_file_writer_.reset();
437445
}
438446

439-
tracing::Agent* GetTracingAgent() const {
440-
return tracing_agent_.get();
447+
tracing::AgentWriterHandle* GetTracingAgentWriter() {
448+
return &tracing_file_writer_;
441449
}
442450

443451
NodePlatform* Platform() {
@@ -466,7 +474,9 @@ static struct {
466474
}
467475
void StopTracingAgent() {}
468476

469-
tracing::Agent* GetTracingAgent() const { return nullptr; }
477+
tracing::AgentWriterHandle* GetTracingAgentWriter() {
478+
return nullptr;
479+
}
470480

471481
NodePlatform* Platform() {
472482
return nullptr;
@@ -3593,7 +3603,7 @@ Environment* CreateEnvironment(IsolateData* isolate_data,
35933603
HandleScope handle_scope(isolate);
35943604
Context::Scope context_scope(context);
35953605
auto env = new Environment(isolate_data, context,
3596-
v8_platform.GetTracingAgent());
3606+
v8_platform.GetTracingAgentWriter());
35973607
env->Start(argc, argv, exec_argc, exec_argv, v8_is_profiling);
35983608
return env;
35993609
}
@@ -3652,7 +3662,7 @@ inline int Start(Isolate* isolate, IsolateData* isolate_data,
36523662
HandleScope handle_scope(isolate);
36533663
Local<Context> context = NewContext(isolate);
36543664
Context::Scope context_scope(context);
3655-
Environment env(isolate_data, context, v8_platform.GetTracingAgent());
3665+
Environment env(isolate_data, context, v8_platform.GetTracingAgentWriter());
36563666
env.Start(argc, argv, exec_argc, exec_argv, v8_is_profiling);
36573667

36583668
const char* path = argc > 1 ? argv[1] : nullptr;

src/node_trace_events.cc

+5-4
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ void NodeCategorySet::New(const FunctionCallbackInfo<Value>& args) {
5858
if (!*val) return;
5959
categories.emplace(*val);
6060
}
61-
CHECK_NOT_NULL(env->tracing_agent());
61+
CHECK_NOT_NULL(env->tracing_agent_writer());
6262
new NodeCategorySet(env, args.This(), std::move(categories));
6363
}
6464

@@ -69,7 +69,7 @@ void NodeCategorySet::Enable(const FunctionCallbackInfo<Value>& args) {
6969
CHECK_NOT_NULL(category_set);
7070
const auto& categories = category_set->GetCategories();
7171
if (!category_set->enabled_ && !categories.empty()) {
72-
env->tracing_agent()->Enable(categories);
72+
env->tracing_agent_writer()->Enable(categories);
7373
category_set->enabled_ = true;
7474
}
7575
}
@@ -81,14 +81,15 @@ void NodeCategorySet::Disable(const FunctionCallbackInfo<Value>& args) {
8181
CHECK_NOT_NULL(category_set);
8282
const auto& categories = category_set->GetCategories();
8383
if (category_set->enabled_ && !categories.empty()) {
84-
env->tracing_agent()->Disable(categories);
84+
env->tracing_agent_writer()->Disable(categories);
8585
category_set->enabled_ = false;
8686
}
8787
}
8888

8989
void GetEnabledCategories(const FunctionCallbackInfo<Value>& args) {
9090
Environment* env = Environment::GetCurrent(args);
91-
std::string categories = env->tracing_agent()->GetEnabledCategories();
91+
std::string categories =
92+
env->tracing_agent_writer()->agent()->GetEnabledCategories();
9293
if (!categories.empty()) {
9394
args.GetReturnValue().Set(
9495
String::NewFromUtf8(env->isolate(),

src/tracing/agent.cc

+44-53
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,24 @@
11
#include "tracing/agent.h"
22

3-
#include <sstream>
43
#include <string>
54
#include "tracing/node_trace_buffer.h"
6-
#include "tracing/node_trace_writer.h"
75

86
namespace node {
97
namespace tracing {
108

11-
namespace {
12-
13-
class ScopedSuspendTracing {
9+
class Agent::ScopedSuspendTracing {
1410
public:
15-
ScopedSuspendTracing(TracingController* controller, Agent* agent)
16-
: controller_(controller), agent_(agent) {
17-
controller->StopTracing();
11+
ScopedSuspendTracing(TracingController* controller, Agent* agent,
12+
bool do_suspend = true)
13+
: controller_(controller), agent_(do_suspend ? agent : nullptr) {
14+
if (do_suspend) {
15+
CHECK(agent_->started_);
16+
controller->StopTracing();
17+
}
1818
}
1919

2020
~ScopedSuspendTracing() {
21+
if (agent_ == nullptr) return;
2122
TraceConfig* config = agent_->CreateTraceConfig();
2223
if (config != nullptr) {
2324
controller_->StartTracing(config);
@@ -29,8 +30,10 @@ class ScopedSuspendTracing {
2930
Agent* agent_;
3031
};
3132

33+
namespace {
34+
3235
std::set<std::string> flatten(
33-
const std::unordered_map<int, std::set<std::string>>& map) {
36+
const std::unordered_map<int, std::multiset<std::string>>& map) {
3437
std::set<std::string> result;
3538
for (const auto& id_value : map)
3639
result.insert(id_value.second.begin(), id_value.second.end());
@@ -43,18 +46,17 @@ using v8::platform::tracing::TraceConfig;
4346
using v8::platform::tracing::TraceWriter;
4447
using std::string;
4548

46-
Agent::Agent(const std::string& log_file_pattern)
47-
: log_file_pattern_(log_file_pattern) {
49+
Agent::Agent() {
4850
tracing_controller_ = new TracingController();
4951
tracing_controller_->Initialize(nullptr);
52+
53+
CHECK_EQ(uv_loop_init(&tracing_loop_), 0);
5054
}
5155

5256
void Agent::Start() {
5357
if (started_)
5458
return;
5559

56-
CHECK_EQ(uv_loop_init(&tracing_loop_), 0);
57-
5860
NodeTraceBuffer* trace_buffer_ = new NodeTraceBuffer(
5961
NodeTraceBuffer::kBufferChunks, this, &tracing_loop_);
6062
tracing_controller_->Initialize(trace_buffer_);
@@ -71,18 +73,30 @@ void Agent::Start() {
7173

7274
AgentWriterHandle Agent::AddClient(
7375
const std::set<std::string>& categories,
74-
std::unique_ptr<AsyncTraceWriter> writer) {
76+
std::unique_ptr<AsyncTraceWriter> writer,
77+
enum UseDefaultCategoryMode mode) {
7578
Start();
79+
80+
const std::set<std::string>* use_categories = &categories;
81+
82+
std::set<std::string> categories_with_default;
83+
if (mode == kUseDefaultCategories) {
84+
categories_with_default.insert(categories.begin(), categories.end());
85+
categories_with_default.insert(categories_[kDefaultHandleId].begin(),
86+
categories_[kDefaultHandleId].end());
87+
use_categories = &categories_with_default;
88+
}
89+
7690
ScopedSuspendTracing suspend(tracing_controller_, this);
7791
int id = next_writer_id_++;
7892
writers_[id] = std::move(writer);
79-
categories_[id] = categories;
93+
categories_[id] = { use_categories->begin(), use_categories->end() };
8094

8195
return AgentWriterHandle(this, id);
8296
}
8397

84-
void Agent::Stop() {
85-
file_writer_.reset();
98+
AgentWriterHandle Agent::DefaultHandle() {
99+
return AgentWriterHandle(this, kDefaultHandleId);
86100
}
87101

88102
void Agent::StopTracing() {
@@ -99,54 +113,30 @@ void Agent::StopTracing() {
99113
}
100114

101115
void Agent::Disconnect(int client) {
116+
if (client == kDefaultHandleId) return;
102117
ScopedSuspendTracing suspend(tracing_controller_, this);
103118
writers_.erase(client);
104119
categories_.erase(client);
105120
}
106121

107-
void Agent::Enable(const std::string& categories) {
122+
void Agent::Enable(int id, const std::set<std::string>& categories) {
108123
if (categories.empty())
109124
return;
110-
std::set<std::string> categories_set;
111-
std::istringstream category_list(categories);
112-
while (category_list.good()) {
113-
std::string category;
114-
getline(category_list, category, ',');
115-
categories_set.emplace(std::move(category));
116-
}
117-
Enable(categories_set);
118-
}
119125

120-
void Agent::Enable(const std::set<std::string>& categories) {
121-
if (categories.empty())
122-
return;
123-
124-
file_writer_categories_.insert(categories.begin(), categories.end());
125-
std::set<std::string> full_list(file_writer_categories_.begin(),
126-
file_writer_categories_.end());
127-
if (file_writer_.empty()) {
128-
// Ensure background thread is running
129-
Start();
130-
std::unique_ptr<NodeTraceWriter> writer(
131-
new NodeTraceWriter(log_file_pattern_, &tracing_loop_));
132-
file_writer_ = AddClient(full_list, std::move(writer));
133-
} else {
134-
ScopedSuspendTracing suspend(tracing_controller_, this);
135-
categories_[file_writer_.id_] = full_list;
136-
}
126+
ScopedSuspendTracing suspend(tracing_controller_, this,
127+
id != kDefaultHandleId);
128+
categories_[id].insert(categories.begin(), categories.end());
137129
}
138130

139-
void Agent::Disable(const std::set<std::string>& categories) {
131+
void Agent::Disable(int id, const std::set<std::string>& categories) {
132+
ScopedSuspendTracing suspend(tracing_controller_, this,
133+
id != kDefaultHandleId);
134+
std::multiset<std::string>& writer_categories = categories_[id];
140135
for (const std::string& category : categories) {
141-
auto it = file_writer_categories_.find(category);
142-
if (it != file_writer_categories_.end())
143-
file_writer_categories_.erase(it);
136+
auto it = writer_categories.find(category);
137+
if (it != writer_categories.end())
138+
writer_categories.erase(it);
144139
}
145-
if (file_writer_.empty())
146-
return;
147-
ScopedSuspendTracing suspend(tracing_controller_, this);
148-
categories_[file_writer_.id_] = { file_writer_categories_.begin(),
149-
file_writer_categories_.end() };
150140
}
151141

152142
TraceConfig* Agent::CreateTraceConfig() const {
@@ -178,5 +168,6 @@ void Agent::Flush(bool blocking) {
178168
for (const auto& id_writer : writers_)
179169
id_writer.second->Flush(blocking);
180170
}
171+
181172
} // namespace tracing
182173
} // namespace node

0 commit comments

Comments
 (0)