Skip to content

Commit

Permalink
fix(grpc): resolve issue with incorrect gRPC response being returned (#…
Browse files Browse the repository at this point in the history
…9157)

The usage of the core API was not correct in the gRPC integration. It
was working on accident based on how the listener was written.

Since the listener mutates the underlying response class and not the
response instance, there is nothing that needs to be returned, so we can
change the `dispatch_with_results` to `dispatch`.

As well, the previous usage of the `dispatch_with_results` API was not
correct, the response was always replaced with the result from the ASM
listener even when the response was `None`.


## Changelog

No changelog entry is added since this is a fix for an unreleased change
so it is not yet a "bug".

## 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] Risks are described (performance impact, potential for breakage,
maintainability)
- [x] Change is maintainable (easy to change, telemetry, documentation)
- [x] [Library release note
guidelines](https://ddtrace.readthedocs.io/en/stable/releasenotes.html)
are followed or label `changelog/no-changelog` is set
- [x] Documentation is included (in-code, generated user docs, [public
corp docs](https://github.com/DataDog/documentation/))
- [x] Backport labels are set (if
[applicable](https://ddtrace.readthedocs.io/en/latest/contributing.html#backporting))
- [x] If this PR changes the public interface, I've notified
`@DataDog/apm-tees`.

## Reviewer Checklist

- [x] Title is accurate
- [x] All changes are related to the pull request's stated goal
- [x] Description motivates each change
- [x] Avoids breaking
[API](https://ddtrace.readthedocs.io/en/stable/versioning.html#interfaces)
changes
- [x] Testing strategy adequately addresses listed risks
- [x] Change is maintainable (easy to change, telemetry, documentation)
- [x] Release note makes sense to a user of the library
- [x] Author has acknowledged and discussed the performance implications
of this PR as reported in the benchmarks PR comment
- [x] Backport labels are set in a manner that is consistent with the
[release branch maintenance
policy](https://ddtrace.readthedocs.io/en/latest/contributing.html#backporting)
  • Loading branch information
brettlangdon authored May 6, 2024
1 parent 434f711 commit 1ca90d5
Show file tree
Hide file tree
Showing 3 changed files with 5 additions and 20 deletions.
3 changes: 1 addition & 2 deletions ddtrace/appsec/_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,6 @@ def _on_grpc_response(response):

msg_cls = type(response)
_patch_protobuf_class(msg_cls)
return response


def listen():
Expand All @@ -425,4 +424,4 @@ def listen():
core.on("flask.patch", _on_flask_patch)

core.on("asgi.request.parse.body", _on_asgi_request_parse_body, "await_receive_and_body")
core.on("grpc.response_message", _on_grpc_response, "response")
core.on("grpc.response_message", _on_grpc_response)
18 changes: 2 additions & 16 deletions ddtrace/contrib/grpc/client_interceptor.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,7 @@ def _handle_response(span, response):
# google-api-core which has its own future base class
# https://github.com/googleapis/python-api-core/blob/49c6755a21215bbb457b60db91bab098185b77da/google/api_core/future/base.py#L23
if hasattr(response, "_response"):
result = core.dispatch_with_results(
"grpc.response_message",
(response._response,),
)
if result:
response_value = result.get("response")
if response_value:
response._response = response_value
core.dispatch("grpc.response_message", (response._response,))

if hasattr(response, "add_done_callback"):
response.add_done_callback(_future_done_callback(span))
Expand Down Expand Up @@ -171,14 +164,7 @@ def _next(self):
def __next__(self):
n = self._next()
if n is not None:
result = core.dispatch_with_results(
"grpc.response_message",
(n,),
)
if result:
response_value = result.get("response")
if response_value:
n = response_value
core.dispatch("grpc.response_message", (n,))
return n

next = __next__
Expand Down
4 changes: 2 additions & 2 deletions ddtrace/internal/core/event_hub.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ def __bool__(self):


class EventResultDict(Dict[str, EventResult]):
def __missing__(self, key: str):
def __missing__(self, key: str) -> EventResult:
return _MissingEvent

def __getattr__(self, name: str):
def __getattr__(self, name: str) -> EventResult:
return dict.__getitem__(self, name)


Expand Down

0 comments on commit 1ca90d5

Please sign in to comment.