Skip to content

Commit 21facfd

Browse files
author
Emanuele Palazzetti
committed
[tornado] auto-patch futures is python 2.7 compatible when futures are not available
1 parent 74846fc commit 21facfd

File tree

4 files changed

+19
-6
lines changed

4 files changed

+19
-6
lines changed

ddtrace/contrib/tornado/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
Auto instrumentation is available using the ``patch`` function that **must be called before**
44
importing the tornado library. The following is an example::
55
6-
# patch before importing tornado
6+
# patch before importing tornado and concurrent.futures
77
from ddtrace import tracer, patch
88
patch(tornado=True)
99

ddtrace/contrib/tornado/compat.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from ..util import require_modules
2+
3+
4+
optional_modules = ['concurrent.futures']
5+
6+
with require_modules(optional_modules) as missing_modules:
7+
# detect if concurrent.futures is available as a Python
8+
# stdlib or Python 2.7 backport
9+
futures_available = len(missing_modules) == 0

ddtrace/contrib/tornado/patch.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
import ddtrace
22
import tornado
3-
import concurrent
43

54
from wrapt import wrap_function_wrapper as _w
65

7-
from . import handlers, application, decorators, template, futures, TracerStackContext
6+
from . import handlers, application, decorators, template, futures, compat, TracerStackContext
87
from ...util import unwrap as _u
98

109

@@ -26,7 +25,7 @@ def patch():
2625
_w('tornado.web', 'RequestHandler.on_finish', handlers.on_finish)
2726
_w('tornado.web', 'RequestHandler.log_exception', handlers.log_exception)
2827

29-
# patch Tornado decorators
28+
# patch Tornado concurrent modules
3029
_w('tornado.concurrent', 'run_on_executor', decorators._run_on_executor)
3130

3231
# patch Template system
@@ -36,7 +35,8 @@ def patch():
3635
# TODO: this may be a generic module and should be moved
3736
# in a separate contributions when we want to support multi-threading
3837
# context propagation
39-
_w('concurrent.futures', 'ThreadPoolExecutor.submit', futures._wrap_submit)
38+
if compat.futures_available:
39+
_w('concurrent.futures', 'ThreadPoolExecutor.submit', futures._wrap_submit)
4040

4141
# configure the global tracer
4242
ddtrace.tracer.configure(
@@ -60,4 +60,6 @@ def unpatch():
6060
_u(tornado.web.Application, '__init__')
6161
_u(tornado.concurrent, 'run_on_executor')
6262
_u(tornado.template.Template, 'generate')
63-
_u(concurrent.futures.ThreadPoolExecutor, 'submit')
63+
64+
if compat.futures_available:
65+
_u('concurrent.futures.ThreadPoolExecutor', 'submit')

tests/contrib/tornado/test_executor_decorator.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import unittest
33

44
from nose.tools import eq_, ok_
5+
from ddtrace.contrib.tornado.compat import futures_available
56

67
from tornado import version_info
78

@@ -43,6 +44,7 @@ def test_on_executor_handler(self):
4344
eq_(0, executor_span.error)
4445
ok_(executor_span.duration >= 0.05)
4546

47+
@unittest.skipUnless(futures_available, 'Futures must be available to test direct submit')
4648
def test_on_executor_submit(self):
4749
# it should propagate the context when a handler uses directly the `executor.submit()`
4850
response = self.fetch('/executor_submit_handler/')

0 commit comments

Comments
 (0)