Skip to content
This repository has been archived by the owner on Jul 1, 2022. It is now read-only.

Add a ActiveSpanSource backed TraceContext #266

Merged
merged 10 commits into from
Oct 11, 2017
Merged

Add a ActiveSpanSource backed TraceContext #266

merged 10 commits into from
Oct 11, 2017

Conversation

vprithvi
Copy link
Contributor

@vprithvi vprithvi commented Oct 9, 2017

  • use ActiveSpanSource for propagation instead of ThreadLocalTraceContext

Signed-off-by: Prithvi Raj [email protected]

- use `ActiveSpanSource` for propagation instead of `ThreadLocalTraceContext`

Signed-off-by: Prithvi Raj <[email protected]>
@ghost ghost assigned vprithvi Oct 9, 2017
@ghost ghost added the review label Oct 9, 2017
@codecov
Copy link

codecov bot commented Oct 9, 2017

Codecov Report

Merging #266 into master will decrease coverage by <.01%.
The diff coverage is 84.37%.

Impacted file tree graph

@@             Coverage Diff              @@
##             master     #266      +/-   ##
============================================
- Coverage      82.3%   82.29%   -0.01%     
- Complexity      530      535       +5     
============================================
  Files            87       87              
  Lines          2006     2022      +16     
  Branches        237      237              
============================================
+ Hits           1651     1664      +13     
- Misses          258      260       +2     
- Partials         97       98       +1
Impacted Files Coverage Δ Complexity Δ
...a/com/uber/jaeger/filters/jaxrs2/ServerFilter.java 95% <100%> (ø) 7 <0> (ø) ⬇️
...r/jaeger/context/ActiveSpanSourceTraceContext.java 82.6% <82.6%> (ø) 8 <8> (?)
...ain/java/com/uber/jaeger/context/TracingUtils.java 88.88% <85.71%> (+38.88%) 5 <5> (+3) ⬆️
...jaeger/reporters/protocols/ThriftUdpTransport.java 77.96% <0%> (-5.09%) 14% <0%> (-2%)
...ger-core/src/main/java/com/uber/jaeger/Tracer.java 86.84% <0%> (+0.43%) 19% <0%> (+1%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 37bd37f...dc4572f. Read the comment docs.

private Span getSpan(ActiveSpan activeSpan) {
Span wrappedSpan;
try {
wrappedSpan = (Span) ActiveSpanSourceTraceContext.wrappedSpan.get(activeSpan);
Copy link
Member

Choose a reason for hiding this comment

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

unnecessary qualifier ActiveSpanSourceTraceContext.

/**
* This is a hack to retrieve the span wrapped by the {@link ThreadLocalActiveSpan} implementation
* to shoehorn into the {@link TraceContext} implementation. This is being done so that
* instrumentation relying on {@link Tracer} has a is consistent with instrumentation using
Copy link
Member

Choose a reason for hiding this comment

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

typo: "has a is"


private final Tracer tracer;
/**
* This is a hack to retrieve the span wrapped by the {@link ThreadLocalActiveSpan} implementation
Copy link
Member

Choose a reason for hiding this comment

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

let's mention that this is a temporary hack until 0.31

* This is a {@link TraceContext} that relies on the {@link ActiveSpanSource} registered with {@link
* GlobalTracer}.
*/
public class ActiveSpanSourceTraceContext implements TraceContext {
Copy link
Member

Choose a reason for hiding this comment

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

Are you sure we need a new class instead of changing ThreadLocalTraceContext? If someone is already using ThreadLocalTraceContext directly, then it won't work correctly any longer, so I think it warrants a breaking API change (namely having an argument to the constructor).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We could also simply remove the ThreadLocalTraceContext instead of marking it @Deprecated

Copy link
Member

Choose a reason for hiding this comment

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

why create extra churn with classes/filenames/history when we can reuse the same class and re-implement it as needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Could you provide justification for sticking with the old name?

The new name is more descriptive.

Javac itself doesn't care about what this class used to be called.

As far as git goes, it uses binary blobs to track file content. I expect it to be able to handle this operation efficiently. Have you seen examples where it hasn't? Should we be optimizing for git history size?

}
}

public ActiveSpanSourceTraceContext(Tracer tracer) {
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 you can use a more narrow dependency, ActiveSpanSource instead of Tracer.
  • instead of depending on ActiveSpanSource, it makes sense to depend directly on ThreadLocalActiveSpanSource

Copy link
Contributor Author

Choose a reason for hiding this comment

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

instead of depending on ActiveSpanSource, it makes sense to depend directly on ThreadLocalActiveSpanSource

This is a bit involved because we need to use reflection to get the instance of the ThreadLocalActiveSpanSource from the tracer. I updated to use the ActiveSpanSource interface instead.

Copy link
Member

Choose a reason for hiding this comment

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

you don't need reflection, just a cast: (ThreadLocalActiveSpanSource) tracer.activeSpanSource()

Copy link
Contributor Author

Choose a reason for hiding this comment

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

tracer.activeSpanSource isn't public. Further, it is defined in com.uber.jaeger.Tracer in jaeger-core, for which we'd have to add a dependency from jaeger-context instead of depending on opentracing-api.

if (!GlobalTracer.isRegistered()) {
throw new IllegalStateException("Please register a io.opentracing.util.GlobalTracer");
}
traceContext = new ActiveSpanSourceTraceContext(GlobalTracer.get());
Copy link
Member

Choose a reason for hiding this comment

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

I am concerned with the race conditions here, as you don't know whether TracingUtils class will be loaded before we have a chance to init global tracer. You may need to change this into a lazy dependency, i.e. instead of passing tracer (or active span source, per the other comment) to the TraceContext impl, you mass a function that returns an active span source, so that it's dereferenced as needed.

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 thought this was was fine because GlobalTracer.get() returns an instance that is a new reference to itself. However, I agree that we cannot guarantee that TracingUtil is loaded after the tracer is initialized. I'll move this to a lazy init block.


Tags.HTTP_STATUS.set(serverSpan, containerResponseContext.getStatus());
serverSpan.finish();
traceContext.pop();
Copy link
Member

Choose a reason for hiding this comment

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

please add comments explaining this order (i.e. that we cannot call pop as before since it will deactivate & finish the span).

Copy link
Member

Choose a reason for hiding this comment

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

is this the only place in the whole project where we call pop?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will do. No, we call it in our wrapped Callable and Runnable

Signed-off-by: Prithvi Raj <[email protected]>
return new TracedExecutorService(wrappedExecutorService, traceContext);
}

private TracingUtils(){}
private static synchronized void initializeTraceContext() {
Copy link
Member

Choose a reason for hiding this comment

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

in my suggestion there was no additional synchronized on the hot path

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 apologize, I didn't understand your previous suggestion, could you elaborate?

As such, getTraceContext and tracedExecutor are only used when initializing filters and executors. I expect these methods to be called a handful of times during application startup.

Copy link
Member

Choose a reason for hiding this comment

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

instead of ActiveSpanSourceTraceContext(Tracer) declare ActiveSpanSourceTraceContext(TracerProvider tracerProvider) and then in the implementation every time you need a tracer you retrieve it dynamically viatracerProvider.get(), which will delegate to GlobalTracer.get(). This way you leave a lot more opportunities to the application to init the global tracer before it stumbles on the need to push/pop spans into TraceContext

Signed-off-by: Prithvi Raj <[email protected]>
private TracingUtils(){}
private static void assertGlobalTracerIsRegistered() {
if (!GlobalTracer.isRegistered()) {
throw new IllegalStateException("Please register a io.opentracing.util.GlobalTracer.");
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@yurishkuro I felt it was simpler to use GlobalTracer.get() directly in ActiveSpanSourceTraceContext. It makes tests dirtier, but it's temporary code.
What is your opinion on the assertGlobalTracerIsRegistered check?

Copy link
Member

Choose a reason for hiding this comment

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

why not pass it the GlobalTracer.INSTANCE as we discussed? By using GlobalTracer directly you're introducing tight coupling in the new class, which didn't need to happen.

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 type of GlobalTracer.INSTANCE is GlobalTracer and I didn't see that as being particularly advantageous because it still couples ActiveSpanSourceTraceContext to the implementation of GlobalTracer.

@yurishkuro
Copy link
Member

Instance implements there Tracer interface, which decouples the new span from GlobalTracer dependency

@vprithvi
Copy link
Contributor Author

Instance implements there Tracer interface, which decouples the new span from GlobalTracer dependency
@yurishkuro My understanding is that we were going to use the GlobalTracer instead of the TracerProvider that you had suggested earlier, and call a getInstance method so that the INSTANCE resolution happens as late as possible. The Tracer interface doesn't provide such a method.

This reverts commit 55d04df.

Signed-off-by: Prithvi Raj <[email protected]>
Signed-off-by: Prithvi Raj <[email protected]>
Signed-off-by: Prithvi Raj <[email protected]>
Signed-off-by: Prithvi Raj <[email protected]>
@vprithvi
Copy link
Contributor Author

@yurishkuro Coveralls diffs against the latest successful build on master. It shows unrelated classes because the build on master failed.

@yurishkuro
Copy link
Member

master build is green now. I restarted this build.

Signed-off-by: Prithvi Raj <[email protected]>
Signed-off-by: Prithvi Raj <[email protected]>
@vprithvi vprithvi merged commit 20573d0 into master Oct 11, 2017
@ghost ghost removed the review label Oct 11, 2017
@vprithvi vprithvi deleted the active-active branch October 11, 2017 21:56
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants