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

Transferring managed span stack from one thread to another #12

Open
objectiser opened this issue Mar 17, 2017 · 17 comments
Open

Transferring managed span stack from one thread to another #12

objectiser opened this issue Mar 17, 2017 · 17 comments

Comments

@objectiser
Copy link
Contributor

As discussed opentracing/specification#23 (comment) in the ongoing in-process context propagation issue, there may be cases where the trace context must be passed from one thread to another completely (possibly as a 'snapshot'), not just supplying the reference to the current span.

There is currently the clear method which disassociates the LinkedManagedSpan from the thread, but no means of associating it with a new thread.

Any thoughts on how this could be done?

@sjoerdtalsma
Copy link
Collaborator

Good point. I hadn't considered this use-case but I can imagine there are situations where this is appropriate. In the current API there's not really a representation for a stack of spans, so I guess without introducing new API concepts or 'leaking' internal representation this would not be easy in the current SpanManager.

@sjoerdtalsma
Copy link
Collaborator

The main difficulty comes from the freedom the SpanManager offers (there is no need for a stack, that's 'incidentally' the way the DefaultSpanManager works).
The manager should be able to capture and reactivate its own internal representation accross threads...

@objectiser
Copy link
Contributor Author

Possibly a simple snapshot mechanism for now?

@sjoerdtalsma
Copy link
Collaborator

The idea was that the ManagedSpan kind of was such a snapshot mechanism 😢 ..
Now the ManagedSpan current() factory method needs to behave different depending on your use-case, but extending the API to accommodate this would make no sense for implementations that don't even maintain a stack at all...
I see the problem, but don't see an obvious solution just yet unfortunately... open to suggestions 😉

@sjoerdtalsma
Copy link
Collaborator

Maybe ManagedSpan should be replaced by Snapshot, but the API needs to be 'told' somehow to push (or even replace??) the whole stack instead of a current span.
How would implementations that don't have stacks behave when given the request?
Should we add an extension interface StackAware or something that defines this additional method?
(really just dumping my ideas here..)

@sjoerdtalsma
Copy link
Collaborator

Mention @bhs so you can follow this issue and think about it with your own work in mind 😉

@objectiser
Copy link
Contributor Author

@sjoerdtalsma agree there is no obvious solution.

I guess there is two separate cases - passing a reference to the current span (handled by activate(Span)) and transferring the complete trace context - but then need to make sure not referenced in multiple threads. Possibly have two new methods - detach() returning ManagedSpan (removing from current thread) and attach(ManagedSpan) - associates with new thread - method names obviously could be changed.

The distinction is based on the use case - activate(Span) is just used to enable the new execution context to reference the parent span in the old execution context - whereas detach/attach is used to transfer the complete trace context between execution contexts?

@objectiser
Copy link
Contributor Author

So it shouldn't matter whether implemented as stack or not - just defines the different semantics required by the application.

@sjoerdtalsma
Copy link
Collaborator

sjoerdtalsma commented Mar 17, 2017

I like the direction you're going with this, but am a little worried about comprehension by people.
The current 'paired' methods can already easily be misunderstood as witnessed in various discussions.
activate / deactivate were actually the result of the recent meeting in Berlin where people were using those terms consistently.

Introducing a second pair of methods for similar but different meaning may be too much.
I like your choices though: attach / detach in my mind implies something as 'glue this to the thread', which comes very close to what you try to do!

@objectiser
Copy link
Contributor Author

Maybe the simplest solution then would be to add an activate(ManagedSpan) but only allow it to be used if the ManagedSpan is free from any other execution context - otherwise an exception could be thrown.

Then the issue is how to mark a ManagedSpan as being free - possibly an internal flag that would be set when the clear method is called?

@sjoerdtalsma
Copy link
Collaborator

We would have to be very clear what it means to activate a managed span (e.g. will any current span be cleared, or can it be restored later?) What will the difference between free / deactivated be?
We can try, but this may well become just as complicated as an additional pair of methods..
😓 ..

@objectiser
Copy link
Contributor Author

Ok lets see if others have any suggestions.

@bhs
Copy link

bhs commented Mar 20, 2017

FWIW, in opentracing/opentracing-java#111 I tried to push callers towards a try-with-resources idiom and a Span-aware Continuation concept. This felt like an easier way to encourage paired method invocations and has other benefits (e.g., dealing with Exceptions naturally).

@objectiser
Copy link
Contributor Author

Hi @sjoerdtalsma , any thoughts on a way forward with this issue? Or would you prefer to leave and we get it sorted in opentracing-java?

@sjoerdtalsma
Copy link
Collaborator

sjoerdtalsma commented Mar 21, 2017

Personally I lean towards:

  • an alternate pair of methods
  • defined in a separate extension interface (as it manages more than a Span)
  • so only stack-based or otherwise complex SpanManager implementations need to implement it
    (for non-complex cases you can simply transfer the Span using current API)

My remaining concern is implementors 'forgetting' to implement that extension interface where applicable.
@objectiser Does this make any sense to you? 😉

@sjoerdtalsma
Copy link
Collaborator

sjoerdtalsma commented Mar 21, 2017

@bhs

I tried to push callers towards a try-with-resources idiom and a Span-aware Continuation concept. This felt like an easier way to encourage paired method invocations

That's actually what ManagedSpan does too, but I made close() an explicit alias for deactivate() to be clear about its purpose.
By the way: I prefer your name Continuation over ManagedSpan.
(just maybe include Span somewhere to be clear about what is continued, given this issue which seems to be wanting for a continuation transfer of the entire stack) ?

@objectiser
Copy link
Contributor Author

@sjoerdtalsma Yes that makes sense. Any idea when it could be available? :)

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

No branches or pull requests

3 participants