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

fix(tracing): lazy importing asyncio should not reset existing trace context [backport 2.7] #9334

Merged
merged 4 commits into from
May 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion ddtrace/_trace/provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@ class DefaultContextProvider(BaseContextProvider, DatadogContextMixin):
def __init__(self):
# type: () -> None
super(DefaultContextProvider, self).__init__()
_DD_CONTEXTVAR.set(None)

def _has_active_context(self):
# type: () -> bool
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
fixes:
- |
This fix resolves an issue where importing ``asyncio`` after a trace has already been started will reset the currently active span.
13 changes: 13 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@
from typing import Generator # noqa:F401
from typing import Tuple # noqa:F401
from unittest import mock
import warnings

from _pytest.runner import call_and_report
from _pytest.runner import pytest_runtest_protocol as default_pytest_runtest_protocol
import pytest

import ddtrace
from ddtrace._trace.provider import _DD_CONTEXTVAR
from ddtrace.internal.compat import httplib
from ddtrace.internal.compat import parse
from ddtrace.internal.remoteconfig.client import RemoteConfigClient
Expand Down Expand Up @@ -67,6 +69,17 @@ def test_spans(tracer):
container.reset()


@pytest.fixture(autouse=True)
def clear_context_after_every_test():
try:
yield
finally:
ctx = _DD_CONTEXTVAR.get()
if ctx is not None:
warnings.warn(f"Context was not cleared after test, expected None, got {ctx}")
_DD_CONTEXTVAR.set(None)


@pytest.fixture
def run_python_code_in_subprocess(tmpdir):
def _run(code, **kwargs):
Expand Down
18 changes: 18 additions & 0 deletions tests/contrib/asyncio/test_lazyimport.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import pytest # noqa: I001


@pytest.mark.subprocess()
def test_lazy_import():
import ddtrace.auto # noqa: F401,I001
from ddtrace import tracer # noqa: I001

assert tracer.context_provider.active() is None
span = tracer.trace("itsatest", service="test", resource="resource", span_type="http")
assert tracer.context_provider.active() is span

# Importing asyncio after starting a trace does not remove the current active span
import asyncio # noqa: F401

assert tracer.context_provider.active() is span
span.finish()
assert tracer.context_provider.active() is None
Loading