Skip to content

Commit c18e48d

Browse files
authored
Merge branch 'main' into main
2 parents ad00d07 + 39767ae commit c18e48d

File tree

4 files changed

+38
-6
lines changed

4 files changed

+38
-6
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1414
([#4402](https://github.com/open-telemetry/opentelemetry-python/pull/4402))
1515
- Tolerates exceptions when loading resource detectors via `OTEL_EXPERIMENTAL_RESOURCE_DETECTORS`
1616
([#4373](https://github.com/open-telemetry/opentelemetry-python/pull/4373))
17+
- Disconnect gRPC client stub when shutting down `OTLPSpanExporter`
18+
([#4370](https://github.com/open-telemetry/opentelemetry-python/pull/4370))
1719
- opentelemetry-sdk: fix OTLP exporting of Histograms with explicit buckets advisory
1820
([#4434](https://github.com/open-telemetry/opentelemetry-python/pull/4434))
1921
- opentelemetry-exporter-otlp-proto-grpc: better dependency version range for Python 3.13

exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -243,8 +243,8 @@ def __init__(
243243
) or Compression.NoCompression
244244

245245
if insecure:
246-
self._client = self._stub(
247-
insecure_channel(self._endpoint, compression=compression)
246+
self._channel = insecure_channel(
247+
self._endpoint, compression=compression
248248
)
249249
else:
250250
credentials = _get_credentials(
@@ -253,11 +253,10 @@ def __init__(
253253
OTEL_EXPORTER_OTLP_CLIENT_KEY,
254254
OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE,
255255
)
256-
self._client = self._stub(
257-
secure_channel(
258-
self._endpoint, credentials, compression=compression
259-
)
256+
self._channel = secure_channel(
257+
self._endpoint, credentials, compression=compression
260258
)
259+
self._client = self._stub(self._channel)
261260

262261
self._export_lock = threading.Lock()
263262
self._shutdown = False
@@ -360,6 +359,7 @@ def shutdown(self, timeout_millis: float = 30_000, **kwargs) -> None:
360359
# wait for the last export if any
361360
self._export_lock.acquire(timeout=timeout_millis / 1e3)
362361
self._shutdown = True
362+
self._channel.close()
363363
self._export_lock.release()
364364

365365
@property

exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_metrics_exporter.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -874,6 +874,21 @@ def test_shutdown_wait_last_export(self):
874874
finally:
875875
export_thread.join()
876876

877+
def test_export_over_closed_grpc_channel(self):
878+
# pylint: disable=protected-access
879+
880+
add_MetricsServiceServicer_to_server(
881+
MetricsServiceServicerSUCCESS(), self.server
882+
)
883+
self.exporter.export(self.metrics["sum_int"])
884+
self.exporter.shutdown()
885+
data = self.exporter._translate_data(self.metrics["sum_int"])
886+
with self.assertRaises(ValueError) as err:
887+
self.exporter._client.Export(request=data)
888+
self.assertEqual(
889+
str(err.exception), "Cannot invoke RPC on closed channel!"
890+
)
891+
877892
def test_aggregation_temporality(self):
878893
# pylint: disable=protected-access
879894

exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1017,6 +1017,21 @@ def test_shutdown_wait_last_export(self):
10171017
finally:
10181018
export_thread.join()
10191019

1020+
def test_export_over_closed_grpc_channel(self):
1021+
# pylint: disable=protected-access
1022+
1023+
add_TraceServiceServicer_to_server(
1024+
TraceServiceServicerSUCCESS(), self.server
1025+
)
1026+
self.exporter.export([self.span])
1027+
self.exporter.shutdown()
1028+
data = self.exporter._translate_data([self.span])
1029+
with self.assertRaises(ValueError) as err:
1030+
self.exporter._client.Export(request=data)
1031+
self.assertEqual(
1032+
str(err.exception), "Cannot invoke RPC on closed channel!"
1033+
)
1034+
10201035

10211036
def _create_span_with_status(status: SDKStatus):
10221037
span = _Span(

0 commit comments

Comments
 (0)