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

Allow multiple context propagators #104

Merged
merged 8 commits into from
Apr 13, 2021

Conversation

RassK
Copy link
Contributor

@RassK RassK commented Apr 5, 2021

Background

This PR adds support for multiple propagators that's required by the OTel standard. (following comment in PR #92)

What's next

Configuration source needs to be validated in early startup time. After that point settings instance should be considered as guaranteed OK (no throwing later in run time). See comments:

@@ -119,7 +119,8 @@ internal Tracer(TracerSettings settings, ITraceWriter traceWriter, ISampler samp
_scopeManager = scopeManager ?? new AsyncLocalScopeManager();
Sampler = sampler ?? new RuleBasedSampler(new RateLimiter(Settings.MaxTracesSubmittedPerSecond));

_propagator = ContextPropagatorBuilder.BuildPropagator(Settings.Propagator, TraceIdConvention);
var propagators = ContextPropagatorBuilder.BuildPropagators(Settings.Propagators, TraceIdConvention);
Copy link
Contributor Author

@RassK RassK Apr 5, 2021

Choose a reason for hiding this comment

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

Please note the upcoming configuration issue here. PropagatorType should be matched with TraceIdConvention (eg: we can go with name:value based configuration key), cause single convention type could not be accepted for all of the propagators. (See PR #102 comment)

Looking for your thoughts!

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Current result: no support for different TraceIds in same time

@RassK RassK marked this pull request as ready for review April 5, 2021 13:21
@RassK RassK requested a review from a team April 5, 2021 13:21
return typedValue;
}

public static IEnumerable<TEnum> GetTypedValues<TEnum>(this IConfigurationSource source, string key)
Copy link
Member

Choose a reason for hiding this comment

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

how we would know that an invalid value was provided. more context

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 not sure this is the right place to deal with validation. As mentioned in #102 it should fail fast. I would propose configuration source validator in early startup (binding configuration to settings instance). After that point configuration should be valid for whole application.

Copy link
Contributor

Choose a reason for hiding this comment

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

For now, would you consider making this use Enum.Parse and throw an exception so we know that the result is valid? I'd prefer that this PR close with a clear indication of configuration errors, so this change might be easier than doing a configuration source validator right now

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Originally I tried not to change parsing logic with this PR (notice the previous logic is 1:1 same as now) but I can easily change it there is interest.

Copy link
Member

@pellared pellared Apr 10, 2021

Choose a reason for hiding this comment

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

I suggest doing it separately.

?? Enumerable.Empty<string>();
}

public static TEnum GetTypedValue<TEnum>(this IConfigurationSource source, string key)
Copy link
Member

Choose a reason for hiding this comment

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

how we would know that an invalid value was provided. more context

Comment on lines -188 to -200

private static void AssertExpected(IHeadersCollection headers, string key, string expected)
{
var matches = headers.GetValues(key);
Assert.Single(matches);
matches.ToList().ForEach(x => Assert.Equal(expected, x));
}

private static void AssertMissing(IHeadersCollection headers, string key)
{
var matches = headers.GetValues(key);
Assert.Empty(matches);
}
Copy link
Member

Choose a reason for hiding this comment

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

why these methods have been moved?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Reused for CompositeTextMapPropagatorTests, HeadersCollectionTestBase seems to be ideal for tests that deal with headers.

Copy link
Member

Choose a reason for hiding this comment

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

I see. Only AssertMissing is not reused there but I think we can keep it as you refactored 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep, both seemed to be generic / reusable. Seems bit weird to leave one out 😄

Copy link
Member

@pellared pellared left a comment

Choose a reason for hiding this comment

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

@RassK RassK force-pushed the context-multi-propagation branch from eb98a7e to 701847b Compare April 9, 2021 10:42
@RassK RassK closed this Apr 9, 2021
@RassK RassK reopened this Apr 9, 2021
@@ -29,5 +30,18 @@ public static IEnumerable<object[]> GetHeadersInvalidSamplingPrioritiesCartesian
from invalidSamplingPriority in HeadersCollectionTestHelpers.GetInvalidSamplingPriorities().SelectMany(i => i)
select new[] { header, invalidSamplingPriority };
}

internal static void AssertExpected(IHeadersCollection headers, string key, string expected)
Copy link
Contributor

Choose a reason for hiding this comment

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

You could make this public so you don't have to add an InternalsVisibleTo attribute. This won't be consumed by developers so I don't see any reason to keep this internal

Copy link
Contributor Author

Choose a reason for hiding this comment

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

IHeadersCollection is also internal, that's the original reason.

/// </summary>
internal class CompositeTextMapPropagator : IPropagator
{
private readonly ICollection<IPropagator> _propagators;
Copy link
Contributor

Choose a reason for hiding this comment

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

Could this be an IEnumerable<IPropagator> instead? It looks like this is only used to enumerate values and doesn't do insertions/removals

Copy link
Contributor Author

@RassK RassK Apr 10, 2021

Choose a reason for hiding this comment

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

I usually like to use ICollection when list is actually materialized - so it's quickly visible it's safe to use. With IEnumerable you are also introducing deferred execution, it can easily backfire with context like this.
(for eg if you happen to connect factory with deferred execution, it's perfectly valid code vise, but introduces a major performance loss - so ICollection is also more like a code guard)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In perfect world I would use IReadOnlyCollection, but here it doesn't seem to be a pattern.

Copy link
Member

@pellared pellared Apr 10, 2021

Choose a reason for hiding this comment

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

I agree with @RassK . I am used to use IReadOnlyCollection for such cases . It is IMO more readable as well. Also Resharper and Rider static analysis often stops complaining about multiple enumeration in such cases

@RassK RassK closed this Apr 13, 2021
@RassK RassK reopened this Apr 13, 2021
@zacharycmontoya
Copy link
Contributor

Unit tests failed because of flaky test: Datadog.Trace.Tests.SpanTests.Accurate_Duration. Datadog just merged DataDog/dd-trace-dotnet#1360 that hopefully resolves this permanently

@zacharycmontoya
Copy link
Contributor

Since the test failure is known to be flaky, I'll go ahead and merge

@zacharycmontoya zacharycmontoya merged commit 4de70b3 into open-telemetry:main Apr 13, 2021
@RassK RassK deleted the context-multi-propagation branch April 14, 2021 08:35
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.

6 participants