You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
C# has several features that will likely/hopefully make in-process propagation easier than in Java:
async/await does not require the use of promises/futures.
AsyncLocal is a storage that automatically flows with async execution.
The upcoming Activity type from .NET (very similar to an OpenTracing Span) uses a simple static property Activity.Current that uses AsyncLocal (.NET 4.6 / .NET Core) or CallContext (.NET 4.5) and therefore automatically flows with the async execution. Every Activity that is started sets an existing Activity.Current as its parent (unless the user manually set a ParentId).
However, if we compare this with the current Java PR, the following features are not possible with this system right now:
It's not possible to start an activity without making it active
It's not possible to ignore the active parent
What I'd like to discuss in this issue is whether or not these two things are even necessary in C#!
Question 1: What non-performance use cases exist, where you would NOT want to make a span active?
Thanks to async/await simple use cases like instrumenting outgoing async calls just work and wouldn't even need a separate in-process propagation system:
However, this would be problematic in case of the integrated HttpClient, because it uses a form of decorator pattern to chain together user logic. If the instrumentation code is not the last in the chain, code from inner decorators is not able to access this span.
Not making the span active is therefore not without issues. Also, given that the instrumented code usually does a network call or similar, the potential overhead of writing the AsyncLocal (I don't have numbers for this yet) might be negligible.
From a performance point of view it might therefore very well be ok to always make a span active.
Question 2: What use-cases are there where you would want to ignore the currently active span?
One scenario I can think of right now is a messaging system where you receive an event which was part of a trace and you want to deliberately start a new trace with the work that follows from that event.
Is this a valid scenario for this use case? Are there other examples?
I'd think AsyncLocal would make this quite easy to propagate the values around. I'm not sure why you would want to ignore the active span, but at the same time if that is a feature in other libraries, we should include it here IMO.
References:
C# has several features that will likely/hopefully make in-process propagation easier than in Java:
async
/await
does not require the use of promises/futures.AsyncLocal
is a storage that automatically flows with async execution.The upcoming
Activity
type from .NET (very similar to an OpenTracingSpan
) uses a simple static propertyActivity.Current
that usesAsyncLocal
(.NET 4.6 / .NET Core) orCallContext
(.NET 4.5) and therefore automatically flows with the async execution. EveryActivity
that is started sets an existingActivity.Current
as its parent (unless the user manually set aParentId
).However, if we compare this with the current Java PR, the following features are not possible with this system right now:
What I'd like to discuss in this issue is whether or not these two things are even necessary in C#!
Question 1: What non-performance use cases exist, where you would NOT want to make a span active?
Thanks to
async
/await
simple use cases like instrumenting outgoing async calls just work and wouldn't even need a separate in-process propagation system:However, this would be problematic in case of the integrated
HttpClient
, because it uses a form of decorator pattern to chain together user logic. If the instrumentation code is not the last in the chain, code from inner decorators is not able to access this span.Not making the span active is therefore not without issues. Also, given that the instrumented code usually does a network call or similar, the potential overhead of writing the AsyncLocal (I don't have numbers for this yet) might be negligible.
From a performance point of view it might therefore very well be ok to always make a span active.
Question 2: What use-cases are there where you would want to ignore the currently active span?
One scenario I can think of right now is a messaging system where you receive an event which was part of a trace and you want to deliberately start a new trace with the work that follows from that event.
Is this a valid scenario for this use case? Are there other examples?
@bhs @dawallin @yurishkuro Would be great if you could provide some feedback. I quickly went through opentracing/specification#23 but most of it were technical details so I haven't found other examples.
/cc @lmolkova @vancem just fyi!
The text was updated successfully, but these errors were encountered: