Skip to content

Commit 45956bd

Browse files
committed
Merge remote-tracking branch 'origin/master' into wip/sessiontracking
2 parents d6daf15 + cdad688 commit 45956bd

6 files changed

Lines changed: 44 additions & 9 deletions

File tree

.travis.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ branches:
2020
- /^release\/.+$/
2121

2222
matrix:
23+
allow_failures:
24+
- python: "3.8-dev"
25+
2326
include:
2427
- python: "3.7"
2528
dist: xenial
@@ -50,14 +53,12 @@ services:
5053
install:
5154
- pip install tox
5255
- pip install codecov
53-
- make install-zeus-cli
5456
- bash scripts/download-semaphore.sh
5557

5658
script:
5759
- coverage erase
5860
- ./scripts/runtox.sh '' --cov=sentry_sdk --cov-report= --cov-branch
5961
- codecov --file .coverage*
60-
- zeus upload -t "application/x-cobertura+xml" .coverage*
6162

6263
notifications:
6364
webhooks:

README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,7 @@ Are you coming from raven-python?
3434

3535
To learn about internals:
3636

37-
- [API Reference (using pdoc)](https://getsentry.github.io/sentry-python/)
38-
- [API Reference (using sphinx)](https://www.pydoc.io/search/?package=sentry-sdk)
37+
- [API Reference](https://getsentry.github.io/sentry-python/)
3938

4039
# License
4140

sentry_sdk/integrations/celery.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,18 @@ def setup_once():
3333
old_build_tracer = trace.build_tracer
3434

3535
def sentry_build_tracer(name, task, *args, **kwargs):
36-
# Need to patch both methods because older celery sometimes
37-
# short-circuits to task.run if it thinks it's safe.
38-
task.__call__ = _wrap_task_call(task, task.__call__)
39-
task.run = _wrap_task_call(task, task.run)
40-
task.apply_async = _wrap_apply_async(task, task.apply_async)
36+
if not getattr(task, "_sentry_is_patched", False):
37+
# Need to patch both methods because older celery sometimes
38+
# short-circuits to task.run if it thinks it's safe.
39+
task.__call__ = _wrap_task_call(task, task.__call__)
40+
task.run = _wrap_task_call(task, task.run)
41+
task.apply_async = _wrap_apply_async(task, task.apply_async)
42+
43+
# `build_tracer` is apparently called for every task
44+
# invocation. Can't wrap every celery task for every invocation
45+
# or we will get infinitely nested wrapper functions.
46+
task._sentry_is_patched = True
47+
4148
return _wrap_tracer(task, old_build_tracer(name, task, *args, **kwargs))
4249

4350
trace.build_tracer = sentry_build_tracer

sentry_sdk/py.typed

Whitespace-only changes.

setup.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
description="Python client for Sentry (https://getsentry.com)",
2020
long_description=__doc__,
2121
packages=find_packages(exclude=("tests", "tests.*")),
22+
# PEP 561
23+
package_data={"typedpkg": ["py.typed"]},
2224
zip_safe=False,
2325
license="BSD",
2426
install_requires=["urllib3", "certifi"],

tests/integrations/celery/test_celery.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ def dummy_task(x, y):
6969
invocation(dummy_task, 1, 0)
7070

7171
event, = events
72+
7273
assert event["contexts"]["trace"]["trace_id"] == span.trace_id
7374
assert event["contexts"]["trace"]["span_id"] != span.span_id
7475
assert event["transaction"] == "dummy_task"
@@ -82,6 +83,31 @@ def dummy_task(x, y):
8283
assert exception["stacktrace"]["frames"][0]["vars"]["foo"] == "42"
8384

8485

86+
def test_no_stackoverflows(celery):
87+
"""We used to have a bug in the Celery integration where its monkeypatching
88+
was repeated for every task invocation, leading to stackoverflows.
89+
90+
See https://github.com/getsentry/sentry-python/issues/265
91+
"""
92+
93+
results = []
94+
95+
@celery.task(name="dummy_task")
96+
def dummy_task():
97+
with configure_scope() as scope:
98+
scope.set_tag("foo", "bar")
99+
100+
results.append(42)
101+
102+
for _ in range(10000):
103+
dummy_task.delay()
104+
105+
assert results == [42] * 10000
106+
107+
with configure_scope() as scope:
108+
assert not scope._tags
109+
110+
85111
def test_simple_no_propagation(capture_events, init_celery):
86112
celery = init_celery(propagate_traces=False)
87113
events = capture_events()

0 commit comments

Comments
 (0)