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

Initial ideal how to refactor provider #1008

Merged
merged 11 commits into from
Aug 6, 2020
Merged

Initial ideal how to refactor provider #1008

merged 11 commits into from
Aug 6, 2020

Conversation

reyang
Copy link
Member

@reyang reyang commented Aug 5, 2020

@codecov
Copy link

codecov bot commented Aug 6, 2020

Codecov Report

Merging #1008 into master will decrease coverage by 1.41%.
The diff coverage is 9.77%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1008      +/-   ##
==========================================
- Coverage   76.98%   75.56%   -1.42%     
==========================================
  Files         220      222       +2     
  Lines        6087     6208     +121     
==========================================
+ Hits         4686     4691       +5     
- Misses       1401     1517     +116     
Impacted Files Coverage Δ
.../OpenTelemetry/Trace/CompositeActivityProcessor.cs 0.00% <0.00%> (ø)
...rc/OpenTelemetry/Trace/TracerProviderExtensions.cs 0.00% <0.00%> (ø)
src/OpenTelemetry/Sdk.cs 63.77% <22.64%> (-30.34%) ⬇️
src/OpenTelemetry/Trace/TracerProviderSdk.cs 100.00% <100.00%> (ø)
src/OpenTelemetry/Metrics/CounterMetricSdkBase.cs 96.66% <0.00%> (+13.33%) ⬆️

@reyang reyang marked this pull request as ready for review August 6, 2020 18:36
@reyang reyang requested a review from a team August 6, 2020 18:36
Copy link
Member

@cijothomas cijothomas left a comment

Choose a reason for hiding this comment

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

LGTM. Will refactor rest of the code based on this. Will add tests and see if all scenarios are addressed.
Thanks!

@cijothomas cijothomas merged commit c4484a7 into master Aug 6, 2020
@cijothomas cijothomas deleted the reyang/refactor branch August 6, 2020 22:35
@@ -161,30 +163,85 @@ public static TracerProvider CreateTracerProvider(Action<TracerProviderBuilder>
return tracerProviderSdk;
}

public static TracerProvider CreateTracerProvider(IEnumerable<string> sources, Sampler sampler = null, Resource resource = null)
Copy link
Member

@CodeBlanch CodeBlanch Aug 6, 2020

Choose a reason for hiding this comment

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

@reyang @cijothomas Can you still call AddActivitySource(...) to add sources? If so should we make it IEnumerable<string> sources = null so you aren't forced to supply something if you want to use the extension? Personally I like the extension better but I'm all for giving users flexibility.

Copy link
Member Author

Choose a reason for hiding this comment

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

I think it depends on what do we expect AddActivitySource to behave:

  • If the expectation is that AddActivitySource can be added at any point of the TraceProvider lifecycle, we should have it.
  • If the expectation is that AddActivitySource can only be applied while we are initializing the TraceProvider, ctor seems to the way as this is what it is designed for.

Copy link
Member Author

Choose a reason for hiding this comment

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

@CodeBlanch as you can see from the commit history, initially I was thinking of having both AddProcessor and AddActivitySource, then I noticed:

  1. The spec wants AddProcessor to happen even after the TraceProvider is created, which wasn't working with the builder approach.
  2. The implementation didn't support changing / adding ActivitySource as this is a restriction from .NET ActivityListener (the Listener.ShoudListenTo value is cached, so subsequent updates will not take effect).

Copy link
Member

Choose a reason for hiding this comment

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

Sorry I'm kind of out of the loop on the pattern we're going for. If it was a builder, you create the instance. Then you build it up. At the end you call .Build and you get the final thing. So I would expect to be able to modify it up until the point build is called, after which I would expect you cannot modify it again. That help?

Copy link
Member Author

Choose a reason for hiding this comment

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

@CodeBlanch correct, the builder approach works in the exact way you've describe.
Which means it doesn't give the flexibility that folks can add processor after the provider got created.

Copy link
Member

Choose a reason for hiding this comment

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

I think we still need some kind of builder. So that exporter authors, instrumentation authors, etc., can add in "Use/Add" extensions. Those are super user friendly! In my mind, the pattern is:

using var tracerProvider = Sdk.CreateTracerProviderBuilder()
   .SetResource(ResourceTags);
   .AddActivitySource("MySource")
   .AddHttpClientInstrumentation()
   .UseJaegerExporter()
   .UseProbabilitySampler(0.5)
   .Build();

Build gives you a fully functioning TracerProvider aka pipeline.

The TracerProvider MAY provide methods to update the configuration.

Spec seems to say it's up to us if we want to allow the tracerProvider to be further modified. I'm impartial, but it doesn't seem unreasonable to also have support via the instance:

tracerProvider.AddProcessor(new MyProcessor());

Which you could do after Build has been called.

🤷

Copy link
Member Author

Choose a reason for hiding this comment

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

Totally, the way I think about this problem - we need the primitive low level APIs that are orthogonal, and user friendly APIs (e.g. builder pattern) that are expressive, make people's life easier + support other patterns such like dependency injection.

The current approach is different, it gives the higher level APIs that are not orthogonal, and make it hard for people who want to access low level functionalities, that's something I'm trying to make a change.

@reyang reyang mentioned this pull request Aug 7, 2020
2 tasks
This was referenced Aug 11, 2020
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.

5 participants