Skip to content

Commit 22625cc

Browse files
authored
Merge pull request #27 from taskbadger/celery-signlas
fix issue where celery signals were not being connected
2 parents 7b8813f + 2a96ae2 commit 22625cc

File tree

3 files changed

+49
-3
lines changed

3 files changed

+49
-3
lines changed

taskbadger/systems/celery.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ def __init__(self, auto_track_tasks=True, includes=None, excludes=None):
2121
self.includes = includes
2222
self.excludes = excludes
2323

24+
if auto_track_tasks:
25+
# Importing this here ensures that the Celery signal handlers are registered
26+
import taskbadger.celery # noqa
27+
2428
def track_task(self, task_name):
2529
if not self.auto_track_tasks:
2630
return False

tests/test_celery_system_integration.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,12 @@
88
Celery runner thread will not have the configuration set.
99
"""
1010
import logging
11+
import sys
12+
import weakref
1113
from unittest import mock
1214

1315
import pytest
16+
from celery.signals import task_prerun
1417

1518
from taskbadger.mug import Badger, Settings
1619
from taskbadger.systems.celery import CelerySystemIntegration
@@ -77,3 +80,36 @@ def add_normal(self, a, b):
7780
def test_task_name_matching(include, exclude, expected: bool):
7881
integration = CelerySystemIntegration(includes=include, excludes=exclude)
7982
assert integration.track_task("myapp.tasks.export_data") is expected
83+
84+
85+
def test_celery_system_integration_connects_signals():
86+
# clean the slate
87+
_disconnect_signals()
88+
if "taskbadger.celery" in sys.modules:
89+
del sys.modules["taskbadger.celery"]
90+
assert "taskbadger.celery" not in sys.modules
91+
92+
# this should result in the signals being connected
93+
CelerySystemIntegration()
94+
95+
assert "taskbadger.celery" in sys.modules
96+
_assert_signals()
97+
98+
99+
def _assert_signals(check_is_connected=True):
100+
# test that signals are actually connected
101+
receivers = [rcv[1] for rcv in task_prerun.receivers]
102+
receiver_names = set()
103+
for receiver in receivers:
104+
if isinstance(receiver, weakref.ReferenceType):
105+
receiver = receiver()
106+
receiver_names.add(f"{receiver.__module__}.{receiver.__name__}")
107+
is_connected = "taskbadger.celery.task_prerun_handler" in receiver_names
108+
assert check_is_connected == is_connected
109+
110+
111+
def _disconnect_signals():
112+
from taskbadger.celery import task_prerun_handler
113+
114+
task_prerun.disconnect(task_prerun_handler)
115+
_assert_signals(check_is_connected=False)

tests/test_session.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,15 @@ def test_session_multiple_threads():
5656
threads.append(t)
5757
t.start()
5858

59-
for t in threads:
60-
t.join(1)
61-
assert not t.is_alive()
59+
loopcount = 0
60+
max_loops = len(threads) * 2
61+
while len(threads):
62+
threads[0].join(1)
63+
if not threads[0].is_alive():
64+
threads.pop(0)
65+
loopcount += 1
66+
if loopcount > max_loops:
67+
pytest.fail("Threads did not complete")
6268

6369
assert len(clients) == num_tasks
6470
assert len({id(s) for s in clients}) == 10

0 commit comments

Comments
 (0)