Skip to content

Commit

Permalink
Add simple scope management whenever a context is attached (#3159)
Browse files Browse the repository at this point in the history
Add simple scope management whenever a context is attached

* create a new otel context `_SCOPES_KEY` that will hold a tuple of
  `(curent_scope, isolation_scope)`
* the `current_scope` will always be forked (like on every span creation/context update in practice)
  * note that this is on `attach`, so not on all copy-on-write context
    object creation but only on apis such as
    [`trace.use_span`](https://github.com/open-telemetry/opentelemetry-python/blob/ba22b165471bde2037620f2c850ab648a849fbc0/opentelemetry-api/src/opentelemetry/trace/__init__.py#L547)
    or [`tracer.start_as_current_span`](https://github.com/open-telemetry/opentelemetry-python/blob/ba22b165471bde2037620f2c850ab648a849fbc0/opentelemetry-api/src/opentelemetry/trace/__init__.py#L329)
  * basically every otel `context` fork corresponds to our `current_scope` fork
* the `isolation_scope` currently will not be forked
  * these will later be updated, for instance when we update our top
    level scope apis that fork isolation scope, that will also have a
    corresponding change in this `attach` function
  • Loading branch information
sl0thentr0py authored Jul 9, 2024
1 parent 4f9257d commit cd3e140
Showing 1 changed file with 19 additions and 7 deletions.
26 changes: 19 additions & 7 deletions sentry_sdk/integrations/opentelemetry/contextvars_context.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,26 @@
from opentelemetry.context.context import Context
from opentelemetry.context import Context, create_key, get_value, set_value
from opentelemetry.context.contextvars_context import ContextVarsRuntimeContext

from sentry_sdk.scope import Scope


_SCOPES_KEY = create_key("sentry_scopes")


class SentryContextVarsRuntimeContext(ContextVarsRuntimeContext):
def attach(self, context):
# type: (Context) -> object
# TODO-neel-potel do scope management
return super().attach(context)
scopes = get_value(_SCOPES_KEY, context)

if scopes and isinstance(scopes, tuple):
(current_scope, isolation_scope) = scopes
else:
current_scope = Scope.get_current_scope()
isolation_scope = Scope.get_isolation_scope()

# TODO-neel-potel fork isolation_scope too like JS
# once we setup our own apis to pass through to otel
new_scopes = (current_scope.fork(), isolation_scope)
new_context = set_value(_SCOPES_KEY, new_scopes, context)

def detach(self, token):
# type: (object) -> None
# TODO-neel-potel not sure if we need anything here, see later
super().detach(token)
return super().attach(new_context)

0 comments on commit cd3e140

Please sign in to comment.