Skip to content

Commit 0f508e1

Browse files
authored
TraceSegment can outlive Tracer (#89)
* TraceSegment can outlive Tracer * remove comment It looks like there's a typo at the beginning, and I couldn't think of a good way to describe `client_id` concisely, so probably best to omit the comment.
1 parent bcee9a4 commit 0f508e1

File tree

9 files changed

+74
-23
lines changed

9 files changed

+74
-23
lines changed

src/datadog/datadog_agent.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,8 @@ DatadogAgent::DatadogAgent(
150150
const FinalizedDatadogAgentConfig& config,
151151
const std::shared_ptr<TracerTelemetry>& tracer_telemetry,
152152
const std::shared_ptr<Logger>& logger,
153-
const TracerSignature& tracer_signature, ConfigManager& config_manager)
153+
const TracerSignature& tracer_signature,
154+
const std::shared_ptr<ConfigManager>& config_manager)
154155
: tracer_telemetry_(tracer_telemetry),
155156
clock_(config.clock),
156157
logger_(logger),

src/datadog/datadog_agent.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ class DatadogAgent : public Collector {
6666
DatadogAgent(const FinalizedDatadogAgentConfig&,
6767
const std::shared_ptr<TracerTelemetry>&,
6868
const std::shared_ptr<Logger>&, const TracerSignature& id,
69-
ConfigManager& config_manager);
69+
const std::shared_ptr<ConfigManager>& config_manager);
7070
~DatadogAgent();
7171

7272
Expected<void> send(

src/datadog/remote_config.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "remote_config.h"
22

3+
#include <cassert>
34
#include <cstdint>
45
#include <type_traits>
56
#include <unordered_set>
@@ -64,10 +65,13 @@ ConfigUpdate parse_dynamic_config(const nlohmann::json& j) {
6465
} // namespace
6566

6667
RemoteConfigurationManager::RemoteConfigurationManager(
67-
const TracerSignature& tracer_signature, ConfigManager& config_manager)
68+
const TracerSignature& tracer_signature,
69+
const std::shared_ptr<ConfigManager>& config_manager)
6870
: tracer_signature_(tracer_signature),
6971
config_manager_(config_manager),
70-
client_id_(uuid()) {}
72+
client_id_(uuid()) {
73+
assert(config_manager_);
74+
}
7175

7276
bool RemoteConfigurationManager::is_new_config(
7377
StringView config_path, const nlohmann::json& config_meta) {
@@ -215,11 +219,11 @@ void RemoteConfigurationManager::process_response(const nlohmann::json& json) {
215219
}
216220

217221
void RemoteConfigurationManager::apply_config(Configuration config) {
218-
config_manager_.update(config.content);
222+
config_manager_->update(config.content);
219223
}
220224

221225
void RemoteConfigurationManager::revert_config(Configuration) {
222-
config_manager_.reset();
226+
config_manager_->reset();
223227
}
224228

225229
} // namespace tracing

src/datadog/remote_config.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
// It interacts with the `ConfigManager` to seamlessly apply or revert
1313
// configurations based on responses received from the remote source.
1414

15+
#include <memory>
1516
#include <string>
1617

1718
#include "config_manager.h"
@@ -44,15 +45,16 @@ class RemoteConfigurationManager {
4445
};
4546

4647
TracerSignature tracer_signature_;
47-
ConfigManager& config_manager_;
48-
std::string client_id_; ///< Identifier a `RemoteConfigurationManager`
48+
std::shared_ptr<ConfigManager> config_manager_;
49+
std::string client_id_;
4950

5051
State state_;
5152
std::unordered_map<std::string, Configuration> applied_config_;
5253

5354
public:
54-
RemoteConfigurationManager(const TracerSignature& tracer_signature,
55-
ConfigManager& config_manager);
55+
RemoteConfigurationManager(
56+
const TracerSignature& tracer_signature,
57+
const std::shared_ptr<ConfigManager>& config_manager);
5658

5759
// Construct a JSON object representing the payload to be sent in a remote
5860
// configuration request.

src/datadog/tracer.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ Tracer::Tracer(const FinalizedTracerConfig& config)
3636
Tracer::Tracer(const FinalizedTracerConfig& config,
3737
const std::shared_ptr<const IDGenerator>& generator)
3838
: logger_(config.logger),
39+
config_manager_(std::make_shared<ConfigManager>(config)),
3940
collector_(/* see constructor body */),
4041
defaults_(std::make_shared<SpanDefaults>(config.defaults)),
4142
runtime_id_(config.runtime_id ? *config.runtime_id
@@ -53,7 +54,6 @@ Tracer::Tracer(const FinalizedTracerConfig& config,
5354
extraction_styles_(config.extraction_styles),
5455
hostname_(config.report_hostname ? get_hostname() : nullopt),
5556
tags_header_max_size_(config.tags_header_size),
56-
config_manager_(config),
5757
sampling_delegation_enabled_(config.delegate_trace_sampling) {
5858
if (auto* collector =
5959
std::get_if<std::shared_ptr<Collector>>(&config.collector)) {
@@ -94,7 +94,7 @@ nlohmann::json Tracer::config_json() const {
9494
});
9595
// clang-format on
9696

97-
config.merge_patch(config_manager_.config_json());
97+
config.merge_patch(config_manager_->config_json());
9898

9999
if (hostname_) {
100100
config["hostname"] = *hostname_;
@@ -122,7 +122,7 @@ Span Tracer::create_span(const SpanConfig& config) {
122122
tracer_telemetry_->metrics().tracer.trace_segments_created_new.inc();
123123
const auto segment = std::make_shared<TraceSegment>(
124124
logger_, collector_, tracer_telemetry_,
125-
config_manager_.get_trace_sampler(), span_sampler_, defaults_,
125+
config_manager_->get_trace_sampler(), span_sampler_, defaults_,
126126
runtime_id_, sampling_delegation_enabled_,
127127
false /* sampling_decision_was_delegated_to_me */, injection_styles_,
128128
hostname_, nullopt /* origin */, tags_header_max_size_,
@@ -293,7 +293,7 @@ Expected<Span> Tracer::extract_span(const DictReader& reader,
293293
tracer_telemetry_->metrics().tracer.trace_segments_created_continued.inc();
294294
const auto segment = std::make_shared<TraceSegment>(
295295
logger_, collector_, tracer_telemetry_,
296-
config_manager_.get_trace_sampler(), span_sampler_, defaults_,
296+
config_manager_->get_trace_sampler(), span_sampler_, defaults_,
297297
runtime_id_, sampling_delegation_enabled_, delegate_sampling_decision,
298298
injection_styles_, hostname_, std::move(origin), tags_header_max_size_,
299299
std::move(trace_tags), std::move(sampling_decision),

src/datadog/tracer.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
// obtained from a `TracerConfig` via the `finalize_config` function. See
1111
// `tracer_config.h`.
1212

13+
#include <cstddef>
14+
#include <memory>
15+
1316
#include "clock.h"
1417
#include "config_manager.h"
1518
#include "error.h"
@@ -32,6 +35,7 @@ class SpanSampler;
3235

3336
class Tracer {
3437
std::shared_ptr<Logger> logger_;
38+
std::shared_ptr<ConfigManager> config_manager_;
3539
std::shared_ptr<Collector> collector_;
3640
std::shared_ptr<const SpanDefaults> defaults_;
3741
RuntimeID runtime_id_;
@@ -44,7 +48,6 @@ class Tracer {
4448
std::vector<PropagationStyle> extraction_styles_;
4549
Optional<std::string> hostname_;
4650
std::size_t tags_header_max_size_;
47-
ConfigManager config_manager_;
4851
bool sampling_delegation_enabled_;
4952

5053
public:

test/test_remote_config.cpp

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ REMOTE_CONFIG_TEST("first payload") {
2828
TracerConfig config;
2929
config.defaults.service = "testsvc";
3030
config.defaults.environment = "test";
31-
ConfigManager config_manager(*finalize_config(config));
31+
const auto config_manager =
32+
std::make_shared<ConfigManager>(*finalize_config(config));
3233

3334
RemoteConfigurationManager rc(tracer_signature, config_manager);
3435

@@ -62,7 +63,8 @@ REMOTE_CONFIG_TEST("response processing") {
6263
config.defaults.service = "testsvc";
6364
config.defaults.environment = "test";
6465
config.trace_sampler.sample_rate = 1.0;
65-
ConfigManager config_manager(*finalize_config(config));
66+
const auto config_manager =
67+
std::make_shared<ConfigManager>(*finalize_config(config));
6668

6769
RemoteConfigurationManager rc(tracer_signature, config_manager);
6870

@@ -177,9 +179,9 @@ REMOTE_CONFIG_TEST("response processing") {
177179

178180
REQUIRE(!response_json.is_discarded());
179181

180-
const auto old_trace_sampler = config_manager.get_trace_sampler();
182+
const auto old_trace_sampler = config_manager->get_trace_sampler();
181183
rc.process_response(response_json);
182-
const auto new_trace_sampler = config_manager.get_trace_sampler();
184+
const auto new_trace_sampler = config_manager->get_trace_sampler();
183185

184186
CHECK(new_trace_sampler != old_trace_sampler);
185187

@@ -201,7 +203,7 @@ REMOTE_CONFIG_TEST("response processing") {
201203
REQUIRE(!response_json.is_discarded());
202204

203205
rc.process_response(response_json);
204-
const auto current_trace_sampler = config_manager.get_trace_sampler();
206+
const auto current_trace_sampler = config_manager->get_trace_sampler();
205207
CHECK(old_trace_sampler == current_trace_sampler);
206208
}
207209

@@ -227,7 +229,7 @@ REMOTE_CONFIG_TEST("response processing") {
227229
REQUIRE(!response_json.is_discarded());
228230

229231
rc.process_response(response_json);
230-
const auto current_trace_sampler = config_manager.get_trace_sampler();
232+
const auto current_trace_sampler = config_manager->get_trace_sampler();
231233
CHECK(old_trace_sampler == current_trace_sampler);
232234
}
233235
}
@@ -270,9 +272,9 @@ REMOTE_CONFIG_TEST("response processing") {
270272

271273
REQUIRE(!response_json.is_discarded());
272274

273-
const auto old_sampling_rate = config_manager.get_trace_sampler();
275+
const auto old_sampling_rate = config_manager->get_trace_sampler();
274276
rc.process_response(response_json);
275-
const auto new_sampling_rate = config_manager.get_trace_sampler();
277+
const auto new_sampling_rate = config_manager->get_trace_sampler();
276278

277279
CHECK(new_sampling_rate == old_sampling_rate);
278280
}

test/test_trace_segment.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#include <datadog/optional.h>
12
#include <datadog/platform_util.h>
23
#include <datadog/rate.h>
34
#include <datadog/tags.h>
@@ -446,3 +447,24 @@ TEST_CASE("TraceSegment finalization of spans") {
446447
}
447448
}
448449
} // span finalizers
450+
451+
TEST_CASE("independent of Tracer") {
452+
// This test verifies that a `TraceSegment` (via the `Span`s that refer to it)
453+
// can continue to operate even after the `Tracer` that created it is
454+
// destroyed.
455+
//
456+
// Primarily, the test checks that the code doesn't crash in this scenario.
457+
TracerConfig config;
458+
config.defaults.service = "testsvc";
459+
config.defaults.name = "do.thing";
460+
config.logger = std::make_shared<NullLogger>();
461+
462+
auto maybe_tracer = finalize_config(config);
463+
REQUIRE(maybe_tracer);
464+
Optional<Tracer> tracer{*maybe_tracer};
465+
466+
Span root = tracer->create_span();
467+
Span child = root.create_child();
468+
469+
tracer.reset();
470+
}

test/test_tracer.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <ctime>
2424
#include <iosfwd>
2525
#include <stdexcept>
26+
#include <utility>
2627

2728
#include "matchers.h"
2829
#include "mocks/collectors.h"
@@ -1702,3 +1703,19 @@ TEST_CASE("heterogeneous extraction") {
17021703

17031704
REQUIRE(writer.items == test_case.expected_injected_headers);
17041705
}
1706+
1707+
TEST_CASE("move semantics") {
1708+
// Verify that `Tracer` can be moved.
1709+
TracerConfig config;
1710+
config.defaults.service = "testsvc";
1711+
config.logger = std::make_shared<NullLogger>();
1712+
config.collector = std::make_shared<MockCollector>();
1713+
1714+
auto finalized_config = finalize_config(config);
1715+
REQUIRE(finalized_config);
1716+
Tracer tracer1{*finalized_config};
1717+
1718+
// This must compile.
1719+
Tracer tracer2{std::move(tracer1)};
1720+
(void)tracer2;
1721+
}

0 commit comments

Comments
 (0)