Skip to content

Commit 401f741

Browse files
Copilotcijothomas
andcommitted
Fix OTLP MetricExporter deadlock by switching to tokio::Mutex
Co-authored-by: cijothomas <[email protected]>
1 parent b60dab6 commit 401f741

File tree

1 file changed

+26
-26
lines changed

1 file changed

+26
-26
lines changed

opentelemetry-otlp/src/exporter/tonic/metrics.rs

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use core::fmt;
2-
use std::sync::Mutex;
2+
use tokio::sync::Mutex;
33

44
use opentelemetry::otel_debug;
55
use opentelemetry_proto::tonic::collector::metrics::v1::{
@@ -53,27 +53,25 @@ impl TonicMetricsClient {
5353

5454
impl MetricsClient for TonicMetricsClient {
5555
async fn export(&self, metrics: &ResourceMetrics) -> OTelSdkResult {
56-
let (mut client, metadata, extensions) = self
57-
.inner
58-
.lock()
59-
.map_err(|e| OTelSdkError::InternalFailure(format!("Failed to acquire lock: {e:?}")))
60-
.and_then(|mut inner| match &mut *inner {
61-
Some(inner) => {
62-
let (m, e, _) = inner
63-
.interceptor
64-
.call(Request::new(()))
65-
.map_err(|e| {
66-
OTelSdkError::InternalFailure(format!(
67-
"unexpected status while exporting {e:?}"
68-
))
69-
})?
70-
.into_parts();
71-
Ok((inner.client.clone(), m, e))
72-
}
73-
None => Err(OTelSdkError::InternalFailure(
56+
let (mut client, metadata, extensions) = match self.inner.lock().await.as_mut() {
57+
Some(inner) => {
58+
let (m, e, _) = inner
59+
.interceptor
60+
.call(Request::new(()))
61+
.map_err(|e| {
62+
OTelSdkError::InternalFailure(format!(
63+
"unexpected status while exporting {e:?}"
64+
))
65+
})?
66+
.into_parts();
67+
(inner.client.clone(), m, e)
68+
}
69+
None => {
70+
return Err(OTelSdkError::InternalFailure(
7471
"exporter is already shut down".into(),
75-
)),
76-
})?;
72+
))
73+
}
74+
};
7775

7876
otel_debug!(name: "TonicMetricsClient.ExportStarted");
7977

@@ -99,11 +97,13 @@ impl MetricsClient for TonicMetricsClient {
9997
}
10098

10199
fn shutdown(&self) -> OTelSdkResult {
102-
self.inner
103-
.lock()
104-
.map_err(|e| OTelSdkError::InternalFailure(format!("Failed to acquire lock: {e}")))?
105-
.take();
106-
100+
// TODO: Implement actual shutdown
101+
// Due to the use of tokio::sync::Mutex to guard
102+
// the inner client, we need to await the call to lock the mutex
103+
// and that requires async runtime.
104+
// It is possible to fix this by using
105+
// a dedicated thread just to handle shutdown.
106+
// But for now, we just return Ok.
107107
Ok(())
108108
}
109109
}

0 commit comments

Comments
 (0)