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

Brave4 instrument 166 #356

Closed

Conversation

kmaci3k
Copy link

@kmaci3k kmaci3k commented Feb 23, 2017

An attempt to implement requirements mentioned in #166.

Commits are mainly related to attaching context (i.e. for MDC) when some portion of code in done in context of a Span.

@@ -0,0 +1,49 @@
package brave.propagation;

public class TraceContextHolder {
Copy link
Member

Choose a reason for hiding this comment

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

My personal opinion is that we should avoid a class like this that uses statics to keep state. If there was a Factory in between the implementation and the users that would be more desirable to me

Copy link
Author

Choose a reason for hiding this comment

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

I did it in this way because I needed a single object which would keep state for each thread.

I'm wondering how I can achieve similar result using Factory. @devinsba, maybe you have something in mind ?

@@ -61,7 +61,7 @@
.start().flush(); // start the server side and flush instead of processing a response

flushedIncomingRequest.countDown();
// eventhough the client doesn't read the response, we return one
// even though the client doesn't read the response, we return one
Copy link
Member

Choose a reason for hiding this comment

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

hehe

@codefromthecrypt
Copy link
Member

copying in @reta as he's had similar interest

@codefromthecrypt
Copy link
Member

Here are some notes from https://gitter.im/openzipkin/zipkin

General idea

There are two lifetimes: Lifetime of the span and Lifetime of the context

  • The span’s lifetime is start to finish
  • The span has a lifetime within a context (attach/detach from a thread)

https://docs.google.com/document/d/16mKbo6pWKHq30KvYYVSqo6c8uTOTkNLDSgjKwUs1PGs/edit#

Implementation idea

try (Thing attachment = tracer.withCurrentSpan(span)) {
   // now span is in a thread local, MDC whatever
}

This PR is codebase for implementing the attaching part. One thing unlikely is that this would be a hook in the Span type. I think better to be in the Tracer itself, or most separate would be an object that only deals with in-memory context propagation.

The try/finally in this case is a good one for many reasons including that the implicit close is safe (no chance of accidentally bubbling exceptions when reporting etc). Thing above is most likely a sub-type of Closeable which doesn't throw.

Takeaway

from @kmaci3k

if I understand correctly I should do following changes:
Attachment of Span to ThreadLocal should be moved from Span to Tracer (or completely separate object). TraceContext should not have anything to do with attaching to/detaching from ThreadLocal.
tracer.withCurrentSpan(span) should not return Span but an object which just closes current Span, nothing more.

@codefromthecrypt
Copy link
Member

ps while there's no goal to exactly match, and we do want MDC plugin for sure, here's another project that has a somewhat similar api hook. you can play with it to see how it works (Even if there's only a no-op impl) https://github.com/google/instrumentation-java/blob/master/core/src/main/java/com/google/instrumentation/trace/ContextSpanHandler.java

*/
public HttpRequestInterceptor requestInterceptor(final TraceContext parent) {
return (request, context) -> {
Span span = parent == null ? tracer.newTrace() : tracer.newChild(parent);
Copy link
Contributor

Choose a reason for hiding this comment

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

Could we simplify tracer API to support just something like that Span span = tracer.newTrace(parent); so the tracer will make a decision about newTrace / newChild flow?

Copy link
Member

Choose a reason for hiding this comment

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

newTrace would be a bad name, right? because it is not a new trace if there's an existing parent. maybe nextSpan?

Copy link
Contributor

Choose a reason for hiding this comment

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

Agree, nextSpan or startSpan, would be better ones

@Override
public void start(Listener<RespT> responseListener, Metadata headers) {
// TODO: get current span
Span span = tracer.newTrace();
Copy link
Contributor

Choose a reason for hiding this comment

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

Right, a bit relayed to related to previous comment, tracer.newTrace() could make a decision itself based on current span if it has to start a newTrace or newChild ... (TODO item)

@codefromthecrypt
Copy link
Member

here's a first draft of the way to plugin custom thread state handlers #369

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