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

Minor adjustments to the data-pipeline/TraceExporter #388

Merged
merged 4 commits into from
Apr 17, 2024

Conversation

ekump
Copy link
Contributor

@ekump ekump commented Apr 11, 2024

What does this PR do?

Just some minor changes to the TraceExporter.

  • Added some tests around the From trait implementations for TracerTags. These were already tested indirectly.
  • Tweaked the unit tests to test the end result of calling the builder rather than the values of the builder struct fields.
  • Changed no_proxy to use_proxy to be (possibly) clearer and added necessary default trait impl for the builder.
  • Made the TracerTag fields on 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

  • If this PR touches code that signs or publishes builds or packages, or handles credentials of any kind, I've requested a review from @DataDog/security-design-and-guidance.
  • This PR doesn't touch any of that.

@ekump ekump force-pushed the ekump/APMSP-1020-exporter-retry-strat branch from d7e101e to 739b50e Compare April 11, 2024 19:41
assert_eq!(builder.language_version.unwrap(), "1.0");
assert_eq!(builder.interpreter.unwrap(), "v8");

assert_eq!(exporter.tags.tracer_version, "v0.1");
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 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>,
Copy link
Contributor Author

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();
Copy link
Contributor Author

@ekump ekump Apr 11, 2024

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.

Copy link
Contributor

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.

Copy link
Contributor Author

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.

Copy link
Contributor

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.

Copy link
Contributor

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),
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 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.

Copy link
Contributor

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.

Copy link
Contributor

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.

Copy link
Contributor Author

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.

@ekump ekump changed the title Add retry logic to TraceExporter WIP: Add retry logic to TraceExporter Apr 11, 2024
@ekump ekump force-pushed the ekump/APMSP-1020-exporter-retry-strat branch 2 times, most recently from 4a55639 to 89758f4 Compare April 12, 2024 18:54
use_proxy: bool,
}

impl Default for TraceExporterBuilder {
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'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.

@ekump ekump force-pushed the ekump/APMSP-1020-exporter-retry-strat branch from 89758f4 to 66f60f3 Compare April 12, 2024 19:18
@ekump ekump marked this pull request as ready for review April 12, 2024 19:19
@ekump ekump requested a review from a team as a code owner April 12, 2024 19:19
@ekump ekump changed the title WIP: Add retry logic to TraceExporter Add retry logic to TraceExporter Apr 12, 2024
@ekump ekump changed the title Add retry logic to TraceExporter Minor adjustments to the data-pipeline/TraceExporter Apr 15, 2024
@ekump ekump force-pushed the ekump/APMSP-1020-exporter-retry-strat branch 3 times, most recently from 90a24df to 4b5b7db Compare April 15, 2024 15:14
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.
@ekump ekump force-pushed the ekump/APMSP-1020-exporter-retry-strat branch from 4b5b7db to d32aa2f Compare April 17, 2024 12:15
@ekump ekump merged commit f7dadca into main Apr 17, 2024
20 checks passed
@ekump ekump deleted the ekump/APMSP-1020-exporter-retry-strat branch April 17, 2024 13:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants