Skip to content
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

Stacktrace w/ gRPC and generators #10847

Open
jlintz opened this issue Sep 27, 2024 · 0 comments
Open

Stacktrace w/ gRPC and generators #10847

jlintz opened this issue Sep 27, 2024 · 0 comments

Comments

@jlintz
Copy link

jlintz commented Sep 27, 2024

Summary of problem

APM appears to be breaking on python grpc calls, coming from https://github.com/DataDog/dd-trace-py/blob/main/ddtrace/contrib/internal/grpc/client_interceptor.py#L128 when a generator is passed in

We believe a fix would be to initialize _span = None in the above code location as follows...

class _WrappedResponseCallFuture(wrapt.ObjectProxy):
    _span = None
    def __init__(self, wrapped, span):
        # everything else is the same

basic test case:

import wrapt
class _WrappedResponseCallFuture(wrapt.ObjectProxy):
	_span = None 
	def __init__(self, wrapped, span):
		super(_WrappedResponseCallFuture, self).__init__(wrapped)
		self._span = span
		
		
def gen(n):
	yield n
	yield n + 1
	

_WrappedResponseCallFuture(gen, 'foo')

Removing _span = None will break the above code.

Which version of dd-trace-py are you using?

2.9.2

Which version of pip are you using?

n/a

Which libraries and their versions are you using?

Python 3.10
grpcio 1.49.1

How can we reproduce your problem?

What is the result that you get?

~/dev-vscode/.base_universe/glibc-2.31-x86_64/ext/public/python/grpcio/1/49/1/dist/lib/python3.10/grpc/_interceptor.py in __next__(self)
    142 
    143     def __next__(self):
--> 144         raise self._exception
    145 
    146     def next(self):

~/dev-vscode/.base_universe/glibc-2.31-x86_64/ext/public/python/grpcio/1/49/1/dist/lib/python3.10/grpc/_interceptor.py in __call__(self, request, timeout, metadata, credentials, wait_for_ready, compression)
    333 
    334         try:
--> 335             return self._interceptor.intercept_unary_stream(
    336                 continuation, client_call_details, request)
    337         except Exception as exception:  # pylint:disable=broad-except

~/dev-vscode/.base_universe/glibc-2.31-x86_64/ext/public/python/ddtrace/2/9/2/dist/lib/python3.10/ddtrace/contrib/grpc/client_interceptor.py in intercept_unary_stream(self, continuation, client_call_details, request)
    253         )
    254         response_iterator = continuation(client_call_details, request)
--> 255         response_iterator = _WrappedResponseCallFuture(response_iterator, span)
    256         return response_iterator
    257 

~/dev-vscode/.base_universe/glibc-2.31-x86_64/ext/public/python/ddtrace/2/9/2/dist/lib/python3.10/ddtrace/contrib/grpc/client_interceptor.py in __init__(self, wrapped, span)
    128     def __init__(self, wrapped, span):
    129         super(_WrappedResponseCallFuture, self).__init__(wrapped)
--> 130         self._span = span
    131         # Registers callback on the _MultiThreadedRendezvous future to finish
    132         # span in case StopIteration is never raised but RPC is terminated

AttributeError: 'generator' object has no attribute '_span'

What is the result that you expected?

No stacktrace

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant