Skip to content

Commit 5b26e33

Browse files
committed
Fix failing test, lint, and update changelog
- set_attribute and also set_status are not called if span was already ended. Simple reorder of function calls helped - I also realized that accessing end_time is dangerous, in SDK it is protected by lock. I solved this by remembering if we already called end. Calling multiple times end on span is not problematic, but it generates warning logs and is probably not good practice - updated CHANGELOG.md - fix lint
1 parent 5d36a06 commit 5b26e33

3 files changed

Lines changed: 19 additions & 12 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
5151
([#2461](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2461))
5252
- Remove SDK dependency from opentelemetry-instrumentation-grpc
5353
([#2474](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2474))
54+
- `opentelemetry-instrumentation-grpc` User should be able to cancel grpc stream
55+
([#2093](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2093))
5456

5557
## Version 1.24.0/0.45b0 (2024-03-28)
5658

instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/_client.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,20 +74,25 @@ def _safe_invoke(function: Callable, *args):
7474
)
7575

7676

77+
# pylint:disable=abstract-method
7778
class OpenTelemetryStreamWrapper(wrapt.ObjectProxy):
7879
def __init__(self, wrapped, span: trace.Span):
7980
super().__init__(wrapped)
8081
self._self_span = span
82+
self._span_ended = False
8183

8284
def _end_span_if_not_already_ended(self, status_code=None, status=None):
83-
if self._self_span.end_time is None:
84-
self._self_span.end()
85-
if status_code is not None:
86-
self._self_span.set_attribute(
87-
SpanAttributes.RPC_GRPC_STATUS_CODE, status_code
88-
)
89-
if status is not None:
90-
self._self_span.set_status(status)
85+
if self._span_ended:
86+
return
87+
88+
if status_code is not None:
89+
self._self_span.set_attribute(
90+
SpanAttributes.RPC_GRPC_STATUS_CODE, status_code
91+
)
92+
if status is not None:
93+
self._self_span.set_status(status)
94+
self._span_ended = True
95+
self._self_span.end()
9196

9297
def __del__(self):
9398
self._end_span_if_not_already_ended()

instrumentation/opentelemetry-instrumentation-grpc/tests/test_client_interceptor.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -169,8 +169,8 @@ def test_unary_stream(self):
169169

170170
def test_unary_stream_can_be_cancel(self):
171171
responses = server_streaming_method(self._stub, serialize=False)
172-
for i, _ in enumerate(responses):
173-
if i == 1:
172+
for response_num, _ in enumerate(responses):
173+
if response_num == 1:
174174
responses.cancel()
175175
break
176176
spans = self.memory_exporter.get_finished_spans()
@@ -280,8 +280,8 @@ def test_stream_stream(self):
280280

281281
def test_stream_stream_can_be_cancel(self):
282282
responses = bidirectional_streaming_method(self._stub, serialize=False)
283-
for i, _ in enumerate(responses):
284-
if i == 1:
283+
for response_num, _ in enumerate(responses):
284+
if response_num == 1:
285285
responses.cancel()
286286
break
287287
spans = self.memory_exporter.get_finished_spans()

0 commit comments

Comments
 (0)