-
Notifications
You must be signed in to change notification settings - Fork 56
@traced_function now works with AsyncIO's coroutines. #84
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
base: master
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -24,6 +24,16 @@ | |
| import tornado.concurrent | ||
| from . import get_current_span, span_in_stack_context, utils | ||
|
|
||
| try: | ||
| import asyncio | ||
| _ASYNCIO = True | ||
| except Exception: | ||
| _ASYNCIO = False | ||
|
|
||
|
|
||
| def is_asyncio_coroutine(func): | ||
| return False if not _ASYNCIO else asyncio.iscoroutine(func) | ||
nicholasamorim marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
|
|
||
| def func_span(func, tags=None, require_active_trace=False): | ||
| """ | ||
|
|
@@ -128,25 +138,31 @@ def decorator(*args, **kwargs): | |
| with span_in_stack_context(span) as deactivate_cb: | ||
| try: | ||
| res = func(*args, **kwargs) | ||
| is_tornado = tornado.concurrent.is_future(res) | ||
| is_asyncio = is_asyncio_coroutine(res) | ||
| if is_asyncio: | ||
| task = asyncio.create_task(res) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What about span propagation? I'm afraid that it doesn't work properly here, because we add task to asyncio loop and next time asyncio may execute the task in another scope. See https://github.com/opentracing/opentracing-python/blob/master/opentracing/scope_managers/asyncio.py#L37
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, wow, I hadn't seen that. I'm still new to all of this, so.. makes sense. How can that be fixed? I'm guessing this should be fixed at the ScopeManager? What happens on Tornado 6 (no more StackContext) - just use the AsyncIO scope manager?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In my opinion the best way to solve the problem is make auto span propagation in asyncio code (including scheduling tasks) with scope manager. It can work something like this PR opentracing/opentracing-python#118
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hi @nicholasamorim and @condorcet,
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think these changes definitely should be proved, so we have to add some tests first.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I might be way over my head in this but these changes seems to work fine with the changes @condorcet merged on opentracing/opentracing-python#118 I've been using it with the
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @nicholasamorim Behavior of the decorator is different for
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
How different would be? I don't understand the internals enough to see that. Looking at the decorator I'd expect it to be scopemanager-agnostic. Can we "fix" what's different? I can add some unit tests, sure, just trying to understand it all before.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry for delay! Also notice this part of code changed in master. |
||
| else: | ||
| task = res | ||
| # Tornado co-routines usually return futures, so we must wait | ||
| # until the future is completed, in order to accurately | ||
| # capture the function's execution time. | ||
| if tornado.concurrent.is_future(res): | ||
| if is_tornado or is_asyncio: | ||
| def done_callback(future): | ||
| deactivate_cb() | ||
| exception = future.exception() | ||
| if exception is not None: | ||
| span.log(event='exception', payload=exception) | ||
| span.set_tag('error', 'true') | ||
| span.finish() | ||
| if res.done(): | ||
| if task.done(): | ||
| done_callback(res) | ||
| else: | ||
| res.add_done_callback(done_callback) | ||
| task.add_done_callback(done_callback) | ||
| else: | ||
| deactivate_cb() | ||
| span.finish() | ||
| return res | ||
| return task | ||
| except Exception as e: | ||
| deactivate_cb() | ||
| span.log(event='exception', payload=e) | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.