Skip to content

Commit 1ef865b

Browse files
mabdinurP403n1x87
andauthored
fix(telemetry): ensures telemetry threads do block gunicorn workers (backport #5882 to 1.12) (#5919)
Resolves: #5876 ## Checklist - [x] Change(s) are motivated and described in the PR description. - [x] Testing strategy is described if automated tests are not included in the PR. - [x] Risk is outlined (performance impact, potential for breakage, maintainability, etc). - [x] Change is maintainable (easy to change, telemetry, documentation). - [x] [Library release note guidelines](https://ddtrace.readthedocs.io/en/stable/contributing.html#Release-Note-Guidelines) are followed. - [x] Documentation is included (in-code, generated user docs, [public corp docs](https://github.com/DataDog/documentation/)). - [x] OPTIONAL: PR description includes explicit acknowledgement of the performance implications of the change as reported in the benchmarks PR comment. ## Review Checklist - [x] Title is accurate. - [x] No unnecessary changes are introduced. - [x] Description motivates each change. - [x] Avoids breaking [API](https://ddtrace.readthedocs.io/en/stable/versioning.html#interfaces) changes unless absolutely necessary. - [x] Testing strategy adequately addresses listed risk(s). - [x] Change is maintainable (easy to change, telemetry, documentation). - [x] Release note makes sense to a user of the library. - [x] Reviewer has explicitly acknowledged and discussed the performance implications of this PR as reported in the benchmarks PR comment. Co-authored-by: Gabriele N. Tornetta <[email protected]>
1 parent c8aa55e commit 1ef865b

File tree

5 files changed

+22
-5
lines changed

5 files changed

+22
-5
lines changed

.circleci/config.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,7 @@ jobs:
632632

633633
gunicorn:
634634
<<: *machine_executor
635+
parallelism: 4
635636
steps:
636637
- attach_workspace:
637638
at: .

ddtrace/internal/telemetry/writer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ def _restart_sequence(self):
209209
def _stop_service(self, *args, **kwargs):
210210
# type: (...) -> None
211211
super(TelemetryBase, self)._stop_service(*args, **kwargs)
212-
self.join()
212+
self.join(timeout=2)
213213

214214

215215
class TelemetryLogsMetricsWriter(TelemetryBase):
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
fixes:
3+
- |
4+
gunicorn: This fix ensures ddtrace threads do not block the master process from spawning workers when ``DD_TRACE_DEBUG=true``.
5+
This issue impacts gunicorn applications using gevent and ``python<=3.6``.

tests/contrib/gunicorn/test_gunicorn.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ def _gunicorn_settings_factory(
5454
import_auto_in_postworkerinit=False, # type: bool
5555
import_auto_in_app=None, # type: Optional[bool]
5656
enable_module_cloning=False, # type: bool
57+
debug_mode=False, # type: bool
5758
):
5859
# type: (...) -> GunicornServerSettings
5960
"""Factory for creating gunicorn settings with simple defaults if settings are not defined."""
@@ -65,6 +66,7 @@ def _gunicorn_settings_factory(
6566
env["DD_REMOTE_CONFIGURATION_ENABLED"] = str(True)
6667
env["DD_REMOTECONFIG_POLL_INTERVAL_SECONDS"] = str(SERVICE_INTERVAL)
6768
env["DD_PROFILING_UPLOAD_INTERVAL"] = str(SERVICE_INTERVAL)
69+
env["DD_TRACE_DEBUG"] = str(debug_mode)
6870
return GunicornServerSettings(
6971
env=env,
7072
directory=directory,
@@ -151,6 +153,11 @@ def gunicorn_server(gunicorn_server_settings, tmp_path):
151153
use_ddtracerun=False,
152154
import_auto_in_postworkerinit=True,
153155
)
156+
SETTINGS_GEVENT_DDTRACERUN_DEBUGMODE_MODULE_CLONE = _gunicorn_settings_factory(
157+
worker_class="gevent",
158+
debug_mode=True,
159+
enable_module_cloning=True,
160+
)
154161

155162

156163
@pytest.mark.skipif(sys.version_info >= (3, 11), reason="Gunicorn is only supported up to 3.10")
@@ -159,7 +166,9 @@ def gunicorn_server(gunicorn_server_settings, tmp_path):
159166
[
160167
SETTINGS_GEVENT_APPIMPORT,
161168
SETTINGS_GEVENT_POSTWORKERIMPORT,
169+
SETTINGS_GEVENT_DDTRACERUN,
162170
SETTINGS_GEVENT_DDTRACERUN_MODULE_CLONE,
171+
SETTINGS_GEVENT_DDTRACERUN_DEBUGMODE_MODULE_CLONE,
163172
],
164173
)
165174
def test_no_known_errors_occur(gunicorn_server_settings, tmp_path):

tests/contrib/gunicorn/wsgi_mw_app.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,21 @@
22
This app exists to replicate and report on failures and degraded behavior that can arise when using ddtrace with
33
gunicorn
44
"""
5-
import json
65
import os
76

7+
8+
if os.getenv("_DD_TEST_IMPORT_AUTO"):
9+
import ddtrace.auto # noqa: F401 # isort: skip
10+
11+
import json
12+
813
from ddtrace import tracer
914
from ddtrace.contrib.wsgi import DDWSGIMiddleware
1015
from ddtrace.profiling import bootstrap
1116
import ddtrace.profiling.auto # noqa
1217
from tests.webclient import PingFilter
1318

1419

15-
if os.getenv("_DD_TEST_IMPORT_AUTO"):
16-
import ddtrace.auto # noqa: F401 # isort: skip
17-
1820
tracer.configure(
1921
settings={
2022
"FILTERS": [PingFilter()],

0 commit comments

Comments
 (0)