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

In-process propagation - Logic for activating/deactivating spans #35

Closed
cwe1ss opened this issue Apr 26, 2017 · 2 comments
Closed

In-process propagation - Logic for activating/deactivating spans #35

cwe1ss opened this issue Apr 26, 2017 · 2 comments
Assignees

Comments

@cwe1ss
Copy link
Member

cwe1ss commented Apr 26, 2017

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 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:

public async Task<Response> Send(Request r)
{
    using (ISpan span = _tracer.BuildSpan("someWork").Start())
    {
        Response r = await _client.SendAsync(r);

        span.SetTag("status", r.Status);
    }
}

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!

@TerribleDev
Copy link

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.

@cwe1ss cwe1ss modified the milestones: 1.0.0, 0.11.0 Feb 1, 2018
cwe1ss added a commit that referenced this issue Feb 1, 2018
@cwe1ss cwe1ss removed this from the 0.11.0 milestone Feb 10, 2018
@cwe1ss
Copy link
Member Author

cwe1ss commented Feb 10, 2018

Closed, as Java's implementation has been re-worked and we'll just port their stuff.

@cwe1ss cwe1ss closed this as completed Feb 10, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants