Skip to content

Commit c56620e

Browse files
committed
chore(sampling): pr review feedback
1 parent 4f6bd33 commit c56620e

15 files changed

Lines changed: 399 additions & 155 deletions

.codecov.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ component_management:
5555
name: libdd-profiling-ffi # this is a display name, and can be changed freely
5656
paths:
5757
- libdd-profiling-ffi
58+
- component_id: sampling # this is an identifier that should not be changed
59+
name: libdd-sampling # this is a display name, and can be changed freely
60+
paths:
61+
- libdd-sampling
5862
- component_id: sidecar # this is an identifier that should not be changed
5963
name: datadog-sidecar # this is a display name, and can be changed freely
6064
paths:

libdd-common/src/lib.rs

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use anyhow::Context;
1010
use http::uri;
1111
use serde::de::Error;
1212
use serde::{Deserialize, Deserializer, Serialize, Serializer};
13-
use std::sync::{Mutex, MutexGuard};
13+
use std::sync::{Mutex, MutexGuard, RwLock, RwLockReadGuard, RwLockWriteGuard};
1414
use std::{borrow::Cow, ops::Deref, path::PathBuf, str::FromStr};
1515

1616
pub mod azure_app_services;
@@ -90,6 +90,51 @@ impl<T> MutexExt<T> for Mutex<T> {
9090
}
9191
}
9292

93+
/// Extension trait for `RwLock` to provide methods that acquire read/write locks, panicking if
94+
/// the lock is poisoned.
95+
///
96+
/// Mirrors [`MutexExt`] for `RwLock` so callers avoid `#[allow(clippy::unwrap_used)]` at each
97+
/// lock site.
98+
///
99+
/// # Examples
100+
///
101+
/// ```
102+
/// use libdd_common::RwLockExt;
103+
/// use std::sync::{Arc, RwLock};
104+
///
105+
/// let data = Arc::new(RwLock::new(5));
106+
/// let data_clone = Arc::clone(&data);
107+
///
108+
/// std::thread::spawn(move || {
109+
/// let mut num = data_clone.write_or_panic();
110+
/// *num += 1;
111+
/// })
112+
/// .join()
113+
/// .expect("Thread panicked");
114+
///
115+
/// assert_eq!(*data.read_or_panic(), 6);
116+
/// ```
117+
pub trait RwLockExt<T> {
118+
fn read_or_panic(&self) -> RwLockReadGuard<'_, T>;
119+
fn write_or_panic(&self) -> RwLockWriteGuard<'_, T>;
120+
}
121+
122+
impl<T> RwLockExt<T> for RwLock<T> {
123+
#[inline(always)]
124+
#[track_caller]
125+
fn read_or_panic(&self) -> RwLockReadGuard<'_, T> {
126+
#[allow(clippy::unwrap_used)]
127+
self.read().unwrap()
128+
}
129+
130+
#[inline(always)]
131+
#[track_caller]
132+
fn write_or_panic(&self) -> RwLockWriteGuard<'_, T> {
133+
#[allow(clippy::unwrap_used)]
134+
self.write().unwrap()
135+
}
136+
}
137+
93138
pub mod header {
94139
#![allow(clippy::declare_interior_mutable_const)]
95140
use http::{header::HeaderName, HeaderValue};

libdd-sampling/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ required-features = ["v04_span"]
2626
serde = { version = "1.0", features = ["derive"] }
2727
serde_json = "1.0"
2828
lru = "0.16.3"
29+
libdd-common = { path = "../libdd-common", version = "4.0.0" }
2930
libdd-trace-utils = { path = "../libdd-trace-utils", version = "3.0.1", optional = true }
3031

3132
[features]
@@ -34,4 +35,3 @@ v04_span = ["dep:libdd-trace-utils"]
3435
[dev-dependencies]
3536
criterion = "0.5"
3637
libdd-common = { path = "../libdd-common", version = "4.0.0", features = ["bench-utils"] }
37-
libdd-trace-utils = { path = "../libdd-trace-utils", version = "3.0.1" }

libdd-sampling/src/agent_service_sampler.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ use std::{
66
sync::{Arc, RwLock},
77
};
88

9+
use libdd_common::RwLockExt;
10+
911
use crate::rate_sampler::RateSampler;
1012

1113
#[derive(Debug, serde::Deserialize)]
@@ -21,31 +23,31 @@ pub struct ServicesSampler {
2123

2224
impl ServicesSampler {
2325
pub fn get(&self, service: &str) -> Option<RateSampler> {
24-
self.inner.read().unwrap().get(service).cloned()
26+
self.inner.read_or_panic().get(service).cloned()
2527
}
2628

2729
pub fn update_rates<I: IntoIterator<Item = (String, f64)>>(&self, rates: I) {
2830
let new_rates: HashMap<_, _> = rates
2931
.into_iter()
3032
.map(|(s, r)| (s, RateSampler::new(r)))
3133
.collect();
32-
*self.inner.write().unwrap() = new_rates;
34+
*self.inner.write_or_panic() = new_rates;
3335
}
3436

35-
// used for testing purposes
37+
// Test-only inspection helpers.
3638

37-
#[allow(dead_code)]
39+
#[cfg(test)]
3840
pub(crate) fn is_empty(&self) -> bool {
39-
self.inner.read().unwrap().is_empty()
41+
self.inner.read_or_panic().is_empty()
4042
}
4143

42-
#[allow(dead_code)]
44+
#[cfg(test)]
4345
pub(crate) fn len(&self) -> usize {
44-
self.inner.read().unwrap().len()
46+
self.inner.read_or_panic().len()
4547
}
4648

47-
#[allow(dead_code)]
49+
#[cfg(test)]
4850
pub(crate) fn contains_key(&self, service: &str) -> bool {
49-
self.inner.read().unwrap().contains_key(service)
51+
self.inner.read_or_panic().contains_key(service)
5052
}
5153
}

libdd-sampling/src/constants.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright 2025-Present Datadog, Inc. https://www.datadoghq.com/
22
// SPDX-License-Identifier: Apache-2.0
33

4-
//! Shared constants for the datadog_opentelemetry::sampling crate
4+
//! Shared constants for the libdd-sampling crate
55
66
/// Sampling rate limits
77
pub mod rate {

0 commit comments

Comments
 (0)