Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TraceSegment can outlive Tracer #89

Merged
merged 2 commits into from
Jan 15, 2024

Conversation

dgoffredo
Copy link
Contributor

@dgoffredo dgoffredo commented Jan 12, 2024

I was integrating the recent sampling delegation changes into the corresponding feature branch in nginx-datadog, and got some compiler errors. They're due to other changes on the dd-trace-cpp main branch.

In nginx-datadog, and in Envoy, the Tracer is stored as an Optional<Tracer>. A Tracer instance is then moved into the variable.

Since Tracer now has a ConfigManager data member, and ConfigManager has a std::mutex data member, Tracer can no longer be moved (because std::mutex cannot be moved).

One thing I could do is use Optional::emplace to construct the Tracer in place: no move required.

Another thing I could do is make the Tracer's ConfigManager a std::unique_ptr, so that move semantics are preserved.

Yet another thing I could do is use a std::unique_ptr in nginx-datadog and Envoy, so that the Tracer itself does not have to be moved.

So, I went about thinking about this. Then, looking at the dd-trace-cpp code, I noticed something.

Tracer has ConfigManager data member. A reference (pointer) to the ConfigManager is then passed into the DatadogAgent, which is held by shared_ptr in Tracer. The DatadogAgent has a RemoteConfigurationManager data member, which holds a reference (pointer) to the ConfigManager.

My initial design of dd-trace-cpp was such that a TraceSegment could safely outlive the Tracer that created it. The idea was that an application might have a Tracer that gets reassigned when reconfiguration occurs, and this would not affect any traces in flight.

The recent remote configuration changes violate this property, because the lifetime of the ConfigManager is limited to the lifetime of the Tracer that holds it, even though the ConfigManager is referred to by objects that can outlive the Tracer.

This pull request makes the Tracer's ConfigManager a std::shared_ptr, and passes it as a shared_ptr through DatadogAgent and into RemoteConfigurationManager. This way, even if the Tracer is destroyed, the RemoteConfigurationManager still has a valid handle to the ConfigManager.

@dgoffredo dgoffredo requested a review from dmehala January 12, 2024 20:00
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.
@@ -36,6 +36,7 @@ Tracer::Tracer(const FinalizedTracerConfig& config)
Tracer::Tracer(const FinalizedTracerConfig& config,
const std::shared_ptr<const IDGenerator>& generator)
: logger_(config.logger),
config_manager_(std::make_shared<ConfigManager>(config)),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved this up so that it occurs before collector_. This is not at all necessary, since we're talking about shared pointers, but it mirrors what we would do if the collector and the config manager were both held by value.

@pr-commenter
Copy link

pr-commenter bot commented Jan 12, 2024

Benchmarks

Benchmark execution time: 2024-01-12 20:07:58

Comparing candidate commit 8de1e1c in PR branch david.goffredo/trace-segment-can-outlive-tracer with baseline commit bcee9a4 in branch main.

Found 0 performance improvements and 0 performance regressions! Performance is the same for 1 metrics, 0 unstable metrics.

@@ -44,15 +45,16 @@ class RemoteConfigurationManager {
};

TracerSignature tracer_signature_;
ConfigManager& config_manager_;
std::string client_id_; ///< Identifier a `RemoteConfigurationManager`
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

Copy link
Contributor Author

@dgoffredo dgoffredo Jan 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I figured the comment contained a typo:

///< Identifier a `RemoteConfigurationManager`

I'm not sure what the extra /< is doing, and "Identifier" should probably be "Identifies".

Ok, suppose the comment is "Identifies a RemoteConfigurationManager." True enough, but that doesn't really help me understand what client_id_ is or is for. So, I thought about how best to describe client_id_ in a comment. I didn't think of anything that was better than nothing, so I went with nothing.

@@ -10,6 +10,9 @@
// obtained from a `TracerConfig` via the `finalize_config` function. See
// `tracer_config.h`.

#include <cstddef>
Copy link
Collaborator

@dmehala dmehala Jan 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we use std::size_t explicitly, I figured to include a header for it. Could include string as well, but I didn't notice that one.

@dgoffredo
Copy link
Contributor Author

Thanks for the review.

I'll log off after this merge. It's a USA holiday today :D

@dgoffredo dgoffredo merged commit 0f508e1 into main Jan 15, 2024
19 checks passed
@dgoffredo dgoffredo deleted the david.goffredo/trace-segment-can-outlive-tracer branch January 15, 2024 14:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants