opentracing / opentracing-java

OpenTracing API for Java. 🛑 This library is DEPRECATED! https://github.com/opentracing/specification/issues/163
http://opentracing.io
Apache License 2.0
1.68k stars 344 forks source link

ScopeManager for event-loop based frameworks #350

Open ikurovsky opened 5 years ago

ikurovsky commented 5 years ago

Current interface for ScopeManager assumes that there is an implicit link to a certain context working as a storage for active scope/span. For thread-pool oriented applications the default ThreadLocalScopeManager storing the active scope in a thread local variable is a good fit.

How is it supposed to be implemented for models such as Netty/Vert.x where thread-locals are not an option? Usually such details are stored in some kind of request context, but to my knowledge there is no way in Netty to get a current context without an explicit reference and so it is not clear how to implement the ScopeManager#activeSpan() method assuming there's only one tracer and one scope manager.

tylerbenson commented 5 years ago

I don't know of a good way to do this without having a static reference to the context, likely via a threadlocal. Ratpack exposes something like this, Maybe you could add similar hooks into netty?

ashleymercer commented 5 years ago

There are two approaches that I've seen for passing context around (my use case is Scala, where a lot of code is written async, and callbacks aren't guaranteed to execute on the same thread):

In short, you're always going to require some way of passing around a reference to the "current" trace. With ThreadLocal that knowledge is implicitly defined by the current thread, but this breaks down in async / event-based code.

Hohenheimsenberg commented 4 years ago
  • much less intrusive, doesn't require changing existing code
  • can be made to work with third-party libraries
  • trickier to set up / get working correctly
  • difficult to test / mock reliably

I like the second approach, the problem with it is that there are libraries, like couchbase client that uses the GlobalTracer to access the active span. Also implementations like Jaeger always builds spans as child of the active span if not explicitly specified not to.

I haven't tested it, but on Spring webflux I think that building a bean with a request scope could work.