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

Add ScopeManager implementation for in-process propagation #24

Conversation

palazzem
Copy link
Member

@palazzem palazzem commented Nov 14, 2017

Overview

This PR adds in-process context propagation to the reference implementation. It pairs with opentracing/opentracing-python#63 that is required to make it work. All implementation details should be discussed here, while API-related discussions should follow the other PR.

Details

  • Scope and ScopeManager are implemented for in-process propagation
  • The default ScopeManager (and the only one implemented) uses a thread-local storage for in-process propagation
  • start_active() and start_manual() are the new tracing API; both make use of the in-process propagation unless ignore_active_scope flag is set
  • A Scope is automatically finished as default behavior, unless finish_on_close flag is set to False
  • The Tracer API compatibility is tested using the test suite (api_check.py) available in the opentracing-python package. No further tests are required in this package since the ScopeManager parenting is already tested.

References

- "2.7"

install:
- make bootstrap

script:
- make test

- make test lint
Copy link
Member Author

Choose a reason for hiding this comment

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

This could be another PR, but I needed that to ensure the CI runs the lint step.

Copy link
Contributor

Choose a reason for hiding this comment

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

Actually, you could issue a PR right now with this small change and probably get it merged rather soon ;)

def __init__(self):
self._tls_scope = threading.local()

def activate(self, span, finish_on_close=True):
Copy link
Member Author

Choose a reason for hiding this comment

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

finish_on_close is injected in underlying objects; I think it's a reasonable approach since it should be propagated till we reach a Scope.

@@ -11,7 +12,7 @@

class BasicTracer(Tracer):

def __init__(self, recorder=None, sampler=None):
def __init__(self, recorder=None, sampler=None, scope_manager=None):
Copy link
Member Author

Choose a reason for hiding this comment

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

It's reasonable defining a scope_manager in the constructor, since a Tracer should have one and only one ScopeManager for the rest of the execution. Switching it at runtime could lead to unexpected behaviors.

Copy link
Contributor

@carlosalberto carlosalberto Nov 14, 2017

Choose a reason for hiding this comment

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

I agree here with you. My only question is whether we should provide, on default, a noop ScopeManager by default or not. EDIT - oh, never mind, I saw you are setting it to ThreadLocalScopeManager by default right inside __init__(). Maybe set it right as scope_manager=ThreadLocalScopeManager() in the parameter list? That would be more explicit, I'd say...

@@ -22,7 +22,8 @@
platforms='any',
install_requires=[
'protobuf>=3.0.0b2.post2',
'opentracing>=1.2.1,<1.3',
# TODO: pin the right version after the proposal has been merged on master
# 'opentracing>=1.2.1,<1.3',
Copy link
Member Author

Choose a reason for hiding this comment

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

This is a blocker before merging the PR.

@@ -64,6 +90,12 @@ def start_span(
# TODO only the first reference is currently used
parent_ctx = references[0].referenced_context

# retrieve the active SpanContext
Copy link
Member Author

Choose a reason for hiding this comment

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

if we pass child_of= kwarg, we ignore the ScopeManager, correct?

Copy link
Contributor

Choose a reason for hiding this comment

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

In theory multiple parents will be supported - but currently, only one is used. So, yes, if we pass child_of, we ignore the current Scope.

def is_parent(self, parent, span):
# use `Span` ids to check parenting
if parent is None:
return span.parent_id is None
Copy link
Member Author

Choose a reason for hiding this comment

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

Covers the case where is_parent(None, span) returns True if span is a root span.

@palazzem
Copy link
Member Author

@carlosalberto @tedsuo it would be great having a pass on this PR too to better understand the implementation details with the API defined in the other repo.

"""Return the `Span` that's been scoped by this `Scope`."""
return self._span

def close(self):
Copy link
Contributor

Choose a reason for hiding this comment

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

Hey - while porting our python-examples repository, I went through this code and wondered if there's a reason to have Scope.close() call ScopeManager.deactivate() (or similar) instead? That way we would reuse BasicScope lots more, I think - by putting specific stuff in ScopeManager.

That being said, I could prepare a PR if/as needed on this ;)

Copy link
Contributor

Choose a reason for hiding this comment

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

I.e. specially since it would be nice (if possible), to separate BasicScope from the actual ThreadLocalScopeManager implementation ;)

@carlosalberto
Copy link
Contributor

An additional note: could we, in any case, expose ThreadLocalScopeManager as public? The Java effort does expose this 'basic' scope manager - and people could it even if not using/extending BasicTracer.

@carlosalberto
Copy link
Contributor

Shall we close this PR, @palazzem ?

@palazzem
Copy link
Member Author

@carlosalberto sure thing! Thanks for your efforts!

@palazzem palazzem closed this Mar 27, 2018
@palazzem palazzem deleted the palazzem/scope-manager-implementation branch March 27, 2018 08:24
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.

2 participants