Skip to content

Commit ebeeea1

Browse files
lalitbcijothomas
andauthored
Replace once_cell::Lazy with std::sync::OnceLock for global Initialization in OpenTelemetry API crate (#2326)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
1 parent 3d352d8 commit ebeeea1

File tree

5 files changed

+56
-33
lines changed

5 files changed

+56
-33
lines changed

opentelemetry/Cargo.toml

+4-5
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,18 @@ all-features = true
2121
rustdoc-args = ["--cfg", "docsrs"]
2222

2323
[dependencies]
24-
futures-core = { workspace = true }
25-
futures-sink = "0.3"
26-
once_cell = { workspace = true }
24+
futures-core = { workspace = true, optional = true }
25+
futures-sink = { version = "0.3", optional = true }
2726
pin-project-lite = { workspace = true, optional = true }
28-
thiserror = { workspace = true }
27+
thiserror = { workspace = true, optional = true}
2928
tracing = {workspace = true, optional = true} # optional for opentelemetry internal logging
3029

3130
[target.'cfg(all(target_arch = "wasm32", not(target_os = "wasi")))'.dependencies]
3231
js-sys = "0.3.63"
3332

3433
[features]
3534
default = ["trace", "metrics", "logs"]
36-
trace = ["pin-project-lite"]
35+
trace = ["pin-project-lite", "futures-sink", "futures-core", "thiserror"]
3736
metrics = []
3837
testing = ["trace", "metrics"]
3938
logs = []

opentelemetry/src/baggage.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,22 @@
1515
//!
1616
//! [W3C Baggage]: https://w3c.github.io/baggage
1717
use crate::{Context, Key, KeyValue, Value};
18-
use once_cell::sync::Lazy;
1918
use std::collections::{hash_map, HashMap};
2019
use std::fmt;
20+
use std::sync::OnceLock;
2121

22-
static DEFAULT_BAGGAGE: Lazy<Baggage> = Lazy::new(Baggage::default);
22+
static DEFAULT_BAGGAGE: OnceLock<Baggage> = OnceLock::new();
2323

2424
const MAX_KEY_VALUE_PAIRS: usize = 180;
2525
const MAX_BYTES_FOR_ONE_PAIR: usize = 4096;
2626
const MAX_LEN_OF_ALL_PAIRS: usize = 8192;
2727

28+
/// Returns the default baggage, ensuring it is initialized only once.
29+
#[inline]
30+
fn get_default_baggage() -> &'static Baggage {
31+
DEFAULT_BAGGAGE.get_or_init(Baggage::default)
32+
}
33+
2834
/// A set of name/value pairs describing user-defined properties.
2935
///
3036
/// ### Baggage Names
@@ -399,7 +405,7 @@ impl BaggageExt for Context {
399405
}
400406

401407
fn baggage(&self) -> &Baggage {
402-
self.get::<Baggage>().unwrap_or(&DEFAULT_BAGGAGE)
408+
self.get::<Baggage>().unwrap_or(get_default_baggage())
403409
}
404410
}
405411

opentelemetry/src/global/metrics.rs

+10-6
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,33 @@
11
use crate::metrics::{self, Meter, MeterProvider};
22
use crate::InstrumentationScope;
3-
use once_cell::sync::Lazy;
4-
use std::sync::{Arc, RwLock};
3+
use std::sync::{Arc, OnceLock, RwLock};
54

65
type GlobalMeterProvider = Arc<dyn MeterProvider + Send + Sync>;
76

87
/// The global `MeterProvider` singleton.
9-
static GLOBAL_METER_PROVIDER: Lazy<RwLock<GlobalMeterProvider>> =
10-
Lazy::new(|| RwLock::new(Arc::new(crate::metrics::noop::NoopMeterProvider::new())));
8+
static GLOBAL_METER_PROVIDER: OnceLock<RwLock<GlobalMeterProvider>> = OnceLock::new();
9+
10+
#[inline]
11+
fn global_meter_provider() -> &'static RwLock<GlobalMeterProvider> {
12+
GLOBAL_METER_PROVIDER
13+
.get_or_init(|| RwLock::new(Arc::new(crate::metrics::noop::NoopMeterProvider::new())))
14+
}
1115

1216
/// Sets the given [`MeterProvider`] instance as the current global meter
1317
/// provider.
1418
pub fn set_meter_provider<P>(new_provider: P)
1519
where
1620
P: metrics::MeterProvider + Send + Sync + 'static,
1721
{
18-
let mut global_provider = GLOBAL_METER_PROVIDER
22+
let mut global_provider = global_meter_provider()
1923
.write()
2024
.expect("GLOBAL_METER_PROVIDER RwLock poisoned");
2125
*global_provider = Arc::new(new_provider);
2226
}
2327

2428
/// Returns an instance of the currently configured global [`MeterProvider`].
2529
pub fn meter_provider() -> GlobalMeterProvider {
26-
GLOBAL_METER_PROVIDER
30+
global_meter_provider()
2731
.read()
2832
.expect("GLOBAL_METER_PROVIDER RwLock poisoned")
2933
.clone()
+22-9
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,29 @@
11
use crate::propagation::TextMapPropagator;
22
use crate::trace::noop::NoopTextMapPropagator;
3-
use once_cell::sync::Lazy;
4-
use std::sync::RwLock;
3+
use std::sync::{OnceLock, RwLock};
54

65
/// The current global `TextMapPropagator` propagator.
7-
static GLOBAL_TEXT_MAP_PROPAGATOR: Lazy<RwLock<Box<dyn TextMapPropagator + Send + Sync>>> =
8-
Lazy::new(|| RwLock::new(Box::new(NoopTextMapPropagator::new())));
6+
static GLOBAL_TEXT_MAP_PROPAGATOR: OnceLock<RwLock<Box<dyn TextMapPropagator + Send + Sync>>> =
7+
OnceLock::new();
98

109
/// The global default `TextMapPropagator` propagator.
11-
static DEFAULT_TEXT_MAP_PROPAGATOR: Lazy<NoopTextMapPropagator> =
12-
Lazy::new(NoopTextMapPropagator::new);
10+
static DEFAULT_TEXT_MAP_PROPAGATOR: OnceLock<NoopTextMapPropagator> = OnceLock::new();
11+
12+
/// Ensures the `GLOBAL_TEXT_MAP_PROPAGATOR` is initialized with a `NoopTextMapPropagator`.
13+
#[inline]
14+
fn global_text_map_propagator() -> &'static RwLock<Box<dyn TextMapPropagator + Send + Sync>> {
15+
GLOBAL_TEXT_MAP_PROPAGATOR.get_or_init(|| RwLock::new(Box::new(NoopTextMapPropagator::new())))
16+
}
17+
18+
/// Ensures the `DEFAULT_TEXT_MAP_PROPAGATOR` is initialized.
19+
#[inline]
20+
fn default_text_map_propagator() -> &'static NoopTextMapPropagator {
21+
DEFAULT_TEXT_MAP_PROPAGATOR.get_or_init(NoopTextMapPropagator::new)
22+
}
1323

1424
/// Sets the given [`TextMapPropagator`] propagator as the current global propagator.
1525
pub fn set_text_map_propagator<P: TextMapPropagator + Send + Sync + 'static>(propagator: P) {
16-
let _lock = GLOBAL_TEXT_MAP_PROPAGATOR
26+
let _lock = global_text_map_propagator()
1727
.write()
1828
.map(|mut global_propagator| *global_propagator = Box::new(propagator));
1929
}
@@ -23,8 +33,11 @@ pub fn get_text_map_propagator<T, F>(mut f: F) -> T
2333
where
2434
F: FnMut(&dyn TextMapPropagator) -> T,
2535
{
26-
GLOBAL_TEXT_MAP_PROPAGATOR
36+
global_text_map_propagator()
2737
.read()
2838
.map(|propagator| f(&**propagator))
29-
.unwrap_or_else(|_| f(&*DEFAULT_TEXT_MAP_PROPAGATOR as &dyn TextMapPropagator))
39+
.unwrap_or_else(|_| {
40+
let default_propagator = default_text_map_propagator();
41+
f(default_propagator as &dyn TextMapPropagator)
42+
})
3043
}

opentelemetry/src/global/trace.rs

+11-10
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
use crate::trace::{noop::NoopTracerProvider, SpanContext, Status};
22
use crate::InstrumentationScope;
33
use crate::{trace, trace::TracerProvider, Context, KeyValue};
4-
use once_cell::sync::Lazy;
54
use std::borrow::Cow;
65
use std::fmt;
76
use std::mem;
8-
use std::sync::{Arc, RwLock};
7+
use std::sync::{Arc, OnceLock, RwLock};
98
use std::time::SystemTime;
109

1110
/// Allows a specific [`crate::trace::Span`] to be used generically by [`BoxedSpan`]
@@ -360,19 +359,21 @@ impl trace::TracerProvider for GlobalTracerProvider {
360359
}
361360

362361
/// The global `Tracer` provider singleton.
363-
static GLOBAL_TRACER_PROVIDER: Lazy<RwLock<GlobalTracerProvider>> = Lazy::new(|| {
364-
RwLock::new(GlobalTracerProvider::new(
365-
trace::noop::NoopTracerProvider::new(),
366-
))
367-
});
362+
static GLOBAL_TRACER_PROVIDER: OnceLock<RwLock<GlobalTracerProvider>> = OnceLock::new();
363+
364+
#[inline]
365+
fn global_tracer_provider() -> &'static RwLock<GlobalTracerProvider> {
366+
GLOBAL_TRACER_PROVIDER
367+
.get_or_init(|| RwLock::new(GlobalTracerProvider::new(NoopTracerProvider::new())))
368+
}
368369

369370
/// Returns an instance of the currently configured global [`TracerProvider`] through
370371
/// [`GlobalTracerProvider`].
371372
///
372373
/// [`TracerProvider`]: crate::trace::TracerProvider
373374
/// [`GlobalTracerProvider`]: crate::global::GlobalTracerProvider
374375
pub fn tracer_provider() -> GlobalTracerProvider {
375-
GLOBAL_TRACER_PROVIDER
376+
global_tracer_provider()
376377
.read()
377378
.expect("GLOBAL_TRACER_PROVIDER RwLock poisoned")
378379
.clone()
@@ -428,7 +429,7 @@ where
428429
T: trace::Tracer<Span = S> + Send + Sync + 'static,
429430
P: trace::TracerProvider<Tracer = T> + Send + Sync + 'static,
430431
{
431-
let mut tracer_provider = GLOBAL_TRACER_PROVIDER
432+
let mut tracer_provider = global_tracer_provider()
432433
.write()
433434
.expect("GLOBAL_TRACER_PROVIDER RwLock poisoned");
434435
mem::replace(
@@ -440,7 +441,7 @@ where
440441
/// Shut down the current tracer provider. This will invoke the shutdown method on all span processors.
441442
/// span processors should export remaining spans before return
442443
pub fn shutdown_tracer_provider() {
443-
let mut tracer_provider = GLOBAL_TRACER_PROVIDER
444+
let mut tracer_provider = global_tracer_provider()
444445
.write()
445446
.expect("GLOBAL_TRACER_PROVIDER RwLock poisoned");
446447

0 commit comments

Comments
 (0)