Skip to content

Commit 371e686

Browse files
authored
ref(server): Return pick/sampling decisions as enum instead of bool (#4799)
Because I get eternally confused by whether sampled means to keep something or to drop it, let's just avoid the confusion with an enum instead. It's called `PickResult` to not collide with a (dynamic) `SamplingResult`.
1 parent 6b4fc5d commit 371e686

File tree

6 files changed

+59
-31
lines changed

6 files changed

+59
-31
lines changed

relay-server/src/metrics/metric_stats.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ impl MetricStats {
119119
.options
120120
.metric_stats_rollout_rate;
121121

122-
is_rolled_out(organization_id.value(), rate)
122+
is_rolled_out(organization_id.value(), rate).is_keep()
123123
}
124124

125125
fn to_volume_metric(&self, bucket: impl TrackableBucket, outcome: &Outcome) -> Option<Bucket> {

relay-server/src/services/processor.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1389,7 +1389,7 @@ impl EnvelopeProcessorService {
13891389
// If spans were already extracted for an event, we rely on span processing to extract metrics.
13901390
let extract_spans = !spans_extracted.0
13911391
&& project_info.config.features.produces_spans()
1392-
&& utils::sample(global.options.span_extraction_sample_rate.unwrap_or(1.0));
1392+
&& utils::sample(global.options.span_extraction_sample_rate.unwrap_or(1.0)).is_keep();
13931393

13941394
let metrics = crate::metrics_extraction::event::extract_metrics(
13951395
event,
@@ -2933,7 +2933,7 @@ impl EnvelopeProcessorService {
29332933
};
29342934

29352935
let error_sample_rate = global_config.options.cardinality_limiter_error_sample_rate;
2936-
if !limits.exceeded_limits().is_empty() && utils::sample(error_sample_rate) {
2936+
if !limits.exceeded_limits().is_empty() && utils::sample(error_sample_rate).is_keep() {
29372937
for limit in limits.exceeded_limits() {
29382938
relay_log::with_scope(
29392939
|scope| {

relay-server/src/services/processor/ourlog.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ pub fn filter(
2525
.options
2626
.ourlogs_ingestion_sample_rate
2727
.map(sample)
28-
.unwrap_or(true);
28+
.unwrap_or_default();
2929

30-
let action = match logging_disabled || !logs_sampled {
30+
let action = match logging_disabled || logs_sampled.is_discard() {
3131
true => ItemAction::DropSilently,
3232
false => ItemAction::Keep,
3333
};

relay-server/src/services/processor/replay.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ fn handle_replay_recording_item(
261261
match &error {
262262
relay_replays::recording::ParseRecordingError::Compression(e) => {
263263
// 20k errors per day at 0.1% sample rate == 20 logs per day
264-
if sample(0.001) {
264+
if sample(0.001).is_keep() {
265265
relay_log::with_scope(
266266
move |scope| {
267267
scope.add_attachment(relay_log::protocol::Attachment {

relay-server/src/services/processor/span/processing.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ pub fn extract_from_event(
293293
}
294294

295295
if let Some(sample_rate) = global_config.options.span_extraction_sample_rate {
296-
if !sample(sample_rate) {
296+
if sample(sample_rate).is_discard() {
297297
return spans_extracted;
298298
}
299299
}

relay-server/src/utils/pick.rs

Lines changed: 52 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,44 @@
1-
/// Returns `true` if `id` is rolled out with a rollout rate `rate`.
1+
/// Result of a sampling operation, whether to keep or discard something.
2+
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
3+
pub enum PickResult {
4+
/// The item should be kept.
5+
#[default]
6+
Keep,
7+
/// The item should be dropped.
8+
Discard,
9+
}
10+
11+
/// Returns [`PickResult::Keep`] if `id` is rolled out with a rollout rate `rate`.
212
///
313
/// Deterministically makes a rollout decision for an id, usually organization id,
414
/// and rate.
5-
pub fn is_rolled_out(id: u64, rate: f32) -> bool {
6-
((id % 100000) as f32 / 100000.0f32) < rate
15+
pub fn is_rolled_out(id: u64, rate: f32) -> PickResult {
16+
match ((id % 100000) as f32 / 100000.0f32) < rate {
17+
true => PickResult::Keep,
18+
false => PickResult::Discard,
19+
}
720
}
821

9-
/// Returns `true` if the current item should be sampled.
22+
impl PickResult {
23+
/// Returns `true` if the sampling result is [`PickResult::Keep`].
24+
pub fn is_keep(self) -> bool {
25+
matches!(self, PickResult::Keep)
26+
}
27+
28+
/// Returns `true` if the sampling result is [`PickResult::Discard`].
29+
pub fn is_discard(self) -> bool {
30+
!self.is_keep()
31+
}
32+
}
33+
34+
/// Returns [`PickResult::Keep`] if the current item should be sampled.
1035
///
1136
/// The passed `rate` is expected to be `0 <= rate <= 1`.
12-
pub fn sample(rate: f32) -> bool {
13-
(rate >= 1.0) || (rate > 0.0 && rand::random::<f32>() < rate)
37+
pub fn sample(rate: f32) -> PickResult {
38+
match (rate >= 1.0) || (rate > 0.0 && rand::random::<f32>() < rate) {
39+
true => PickResult::Keep,
40+
false => PickResult::Discard,
41+
}
1442
}
1543

1644
#[cfg(test)]
@@ -19,31 +47,31 @@ mod test {
1947

2048
#[test]
2149
fn test_rollout() {
22-
assert!(!is_rolled_out(1, 0.0));
23-
assert!(is_rolled_out(1, 0.0001)); // Id 1 should always be rolled out
24-
assert!(is_rolled_out(1, 0.1));
25-
assert!(is_rolled_out(1, 0.9));
26-
assert!(is_rolled_out(1, 1.0));
27-
28-
assert!(!is_rolled_out(0, 0.0));
29-
assert!(is_rolled_out(0, 1.0));
30-
assert!(!is_rolled_out(100000, 0.0));
31-
assert!(is_rolled_out(100000, 1.0));
32-
assert!(!is_rolled_out(100001, 0.0));
33-
assert!(is_rolled_out(100001, 1.0));
34-
35-
assert!(!is_rolled_out(42, -100.0));
36-
assert!(is_rolled_out(42, 100.0));
50+
assert_eq!(is_rolled_out(1, 0.0), PickResult::Discard);
51+
assert_eq!(is_rolled_out(1, 0.0001), PickResult::Keep); // Id 1 should always be rolled out
52+
assert_eq!(is_rolled_out(1, 0.1), PickResult::Keep);
53+
assert_eq!(is_rolled_out(1, 0.9), PickResult::Keep);
54+
assert_eq!(is_rolled_out(1, 1.0), PickResult::Keep);
55+
56+
assert_eq!(is_rolled_out(0, 0.0), PickResult::Discard);
57+
assert_eq!(is_rolled_out(0, 1.0), PickResult::Keep);
58+
assert_eq!(is_rolled_out(100000, 0.0), PickResult::Discard);
59+
assert_eq!(is_rolled_out(100000, 1.0), PickResult::Keep);
60+
assert_eq!(is_rolled_out(100001, 0.0), PickResult::Discard);
61+
assert_eq!(is_rolled_out(100001, 1.0), PickResult::Keep);
62+
63+
assert_eq!(is_rolled_out(42, -100.0), PickResult::Discard);
64+
assert_eq!(is_rolled_out(42, 100.0), PickResult::Keep);
3765
}
3866

3967
#[test]
4068
fn test_sample() {
41-
assert!(sample(1.0));
42-
assert!(!sample(0.0));
69+
assert_eq!(sample(1.0), PickResult::Keep);
70+
assert_eq!(sample(0.0), PickResult::Discard);
4371

4472
let mut r: i64 = 0;
4573
for _ in 0..10000 {
46-
if sample(0.5) {
74+
if sample(0.5).is_keep() {
4775
r += 1;
4876
} else {
4977
r -= 1;

0 commit comments

Comments
 (0)