-
Notifications
You must be signed in to change notification settings - Fork 7
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
Minor adjustments to the data-pipeline/TraceExporter #388
Conversation
d7e101e
to
739b50e
Compare
assert_eq!(builder.language_version.unwrap(), "1.0"); | ||
assert_eq!(builder.interpreter.unwrap(), "v8"); | ||
|
||
assert_eq!(exporter.tags.tracer_version, "v0.1"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I switched to testing the exporter tags because this test is calling build()
which sets the exporter tags and we should be testing outputs in unit tests, unless we have a special reason not to.
@@ -157,10 +157,10 @@ impl TraceExporter { | |||
pub struct TraceExporterBuilder { | |||
host: Option<String>, | |||
port: Option<u16>, | |||
tracer_version: Option<String>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The unwrapping of the tag values in the build function and the fact that the corresponding TracerTag
values are not optional implies that they aren't actually optional. I switched them to String
since that better signals intent and also leads to a very minor perf improvement in the builder (not a primary concern).
If there are future plans that rely on these values truly being options I can change them back.
@@ -176,25 +176,25 @@ impl TraceExporterBuilder { | |||
} | |||
|
|||
pub fn set_tracer_version(&mut self, tracer_version: &str) -> &mut TraceExporterBuilder { | |||
self.tracer_version = Some(String::from(tracer_version)); | |||
self.tracer_version = tracer_version.to_owned(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've always known to_owned()
to be idiomatic for going from &str
to String
. Happy to revert this if it was done intentionally.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was done intentionally. The reasoning behind it is, at least in this case, the builder won't cross multiple function boundaries. It's called from an init function and it's never reused so it doesn't need to own all the resources. Therefore cloning all the values and then dropping them at the end of the function didn't seem a good choice in terms of memory management. If you foresee any use case in which the builder has to own all the resources go for it if not it's probably better to not allocate all that strings but that's my opinion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nowadays, String::From
and to_owned()
are functionally equivalent, in both cases you're creating a String that the Builder owns. From a style perspective I personally prefer to_owned()
as it looks cleaner (to me) and conveys intention of creating something the builder will own.
If the intention is that the builder should only hold the references, then I can change it to do that. But, is that something we really want to do? Because at the end of the day we probably want TracerTags
to not hold references as they will likely get used in another thread and the function that calls the builder may drop the references before we're done with them?
We could keep TracerTags
members as String
, but have the Builder use &str
and do the clone in the build()
function to defer the memory allocation as long as possible if we think it's worth it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, we might changed it along the way, I'd need to review the commit history to remember why but I think in the beginning we were holding the references. Now it makes sense to me :).
The initial intention was to minimize memory allocations as much as possible but you solved that by using mem::take
later in the build
method.
Regarding to_owned
vs from
, I don't have any clear preference so if it works better for you we can leave that way and favor that option.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm in favor of to_owned
as well.
language_version: self.language_version.clone().unwrap(), | ||
language_interpreter: self.interpreter.clone().unwrap(), | ||
language: self.language.clone().unwrap(), | ||
tracer_version: std::mem::take(&mut self.tracer_version), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't run benchmarks, but using mem::take
is slightly more performant versus to_owned()
because to_owned()
does another memory allocation. mem::take
just swaps the existing value with the default. The downside to this is that the builder doesn't retain values after build()
is called and thus can cause unexpected results if it is reused. I don't think I've ever reused a builder after I finished building, so I don't think it should be a problem? But, I'm happy to change this to to_owned()
if people disagree.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the build
function is destructive in that way, then it should take ownership of the builder with fn build(self) ...
, to avoid misuse.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's fine to also just add a comment for now, and I'll change things when aligning the API with the RFC doc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good call. I updated the builder.
4a55639
to
89758f4
Compare
use_proxy: bool, | ||
} | ||
|
||
impl Default for TraceExporterBuilder { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm split on whether or not this is a good idea. On the one hand, we should avoid negative bool variables like no_proxy
when possible as it can easily lead to confusion versus bools that are affirmatively named. On the other hand, I see why no_proxy
was probably chosen in the first place since we want the default behavior to use the proxy and bools default to false naturally. Instead of using derive Default macro we had to implement it manually which can seem like overkill for just one struct field.
I can see an argument that this change makes the code more complicated in its attempt to make it simpler so I can revert back to no_proxy
if anyone feels strongly.
89758f4
to
66f60f3
Compare
90a24df
to
4b5b7db
Compare
non-optional Remove optionality of TracerTag related fields as they aren't optional. The build method was just unwrapping them, implying that they had to be set. Build currently uses mem::take for these values, which makes the builder not reusable.
affirmatively named booleans are less confusing to work with.
4b5b7db
to
d32aa2f
Compare
What does this PR do?
Just some minor changes to the TraceExporter.
From
trait implementations forTracerTags
. These were already tested indirectly.no_proxy
touse_proxy
to be (possibly) clearer and added necessary default trait impl for the builder.TraceExporterBuilder
non-optional since they weren't actually optional.Motivation
I incorrectly started to work on TraceExporter for APMSP-1020 before I was informed we should be implementing that ticket in the sidecar's trace export logic for now. (We'll address implementing in TraceExporter later).
Additional Notes
Anything else we should know when reviewing?
How to test the change?
Unit tests are in place
For Reviewers
@DataDog/security-design-and-guidance
.