Skip to content

Commit acd5b17

Browse files
committed
chore: use DefaultHasher to spread out nano time jitter
1 parent 8d9d8f2 commit acd5b17

File tree

5 files changed

+50
-21
lines changed

5 files changed

+50
-21
lines changed

opentelemetry-otlp/src/exporter/http/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@ use std::str::FromStr;
2222
use std::sync::{Arc, Mutex};
2323
use std::time::Duration;
2424

25-
#[cfg(feature = "experimental-http-retry")]
26-
use crate::retry_classification::http::classify_http_error;
2725
#[cfg(feature = "experimental-http-retry")]
2826
use crate::retry::{RetryErrorType, RetryPolicy};
27+
#[cfg(feature = "experimental-http-retry")]
28+
use crate::retry_classification::http::classify_http_error;
2929

3030
// Shared HTTP retry functionality
3131
/// HTTP-specific error wrapper for retry classification
@@ -1492,8 +1492,8 @@ mod tests {
14921492
#[test]
14931493
fn test_with_retry_policy() {
14941494
use super::super::HttpExporterBuilder;
1495-
use crate::WithHttpConfig;
14961495
use crate::retry::RetryPolicy;
1496+
use crate::WithHttpConfig;
14971497

14981498
let custom_policy = RetryPolicy {
14991499
max_retries: 5,

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -856,8 +856,8 @@ mod tests {
856856
#[cfg(feature = "experimental-grpc-retry")]
857857
#[test]
858858
fn test_with_retry_policy() {
859-
use crate::WithTonicConfig;
860859
use crate::retry::RetryPolicy;
860+
use crate::WithTonicConfig;
861861

862862
let custom_policy = RetryPolicy {
863863
max_retries: 5,

opentelemetry-otlp/src/retry.rs

Lines changed: 45 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,32 @@
88
//! retries. The function uses error classification to determine retry behavior and can honor
99
//! server-provided throttling hints.
1010
11-
#[cfg(any(feature = "experimental-grpc-retry", feature = "experimental-http-retry"))]
11+
#[cfg(any(
12+
feature = "experimental-grpc-retry",
13+
feature = "experimental-http-retry"
14+
))]
1215
use opentelemetry::otel_warn;
13-
#[cfg(any(feature = "experimental-grpc-retry", feature = "experimental-http-retry"))]
16+
#[cfg(any(
17+
feature = "experimental-grpc-retry",
18+
feature = "experimental-http-retry"
19+
))]
1420
use std::future::Future;
15-
use std::hash::DefaultHasher;
21+
#[cfg(any(
22+
feature = "experimental-grpc-retry",
23+
feature = "experimental-http-retry"
24+
))]
25+
use std::hash::{DefaultHasher, Hasher};
1626
use std::time::Duration;
17-
#[cfg(any(feature = "experimental-grpc-retry", feature = "experimental-http-retry"))]
27+
#[cfg(any(
28+
feature = "experimental-grpc-retry",
29+
feature = "experimental-http-retry"
30+
))]
1831
use std::time::SystemTime;
1932

20-
#[cfg(any(feature = "experimental-grpc-retry", feature = "experimental-http-retry"))]
33+
#[cfg(any(
34+
feature = "experimental-grpc-retry",
35+
feature = "experimental-http-retry"
36+
))]
2137
use opentelemetry_sdk::runtime::Runtime;
2238

2339
/// Classification of errors for retry purposes.
@@ -47,11 +63,17 @@ pub struct RetryPolicy {
4763

4864
/// A runtime stub for when experimental_async_runtime is not enabled.
4965
/// This allows retry policy to be configured but no actual retries occur.
50-
#[cfg(not(any(feature = "experimental-grpc-retry", feature = "experimental-http-retry")))]
66+
#[cfg(not(any(
67+
feature = "experimental-grpc-retry",
68+
feature = "experimental-http-retry"
69+
)))]
5170
#[derive(Debug, Clone, Default)]
5271
pub struct NoOpRuntime;
5372

54-
#[cfg(not(any(feature = "experimental-grpc-retry", feature = "experimental-http-retry")))]
73+
#[cfg(not(any(
74+
feature = "experimental-grpc-retry",
75+
feature = "experimental-http-retry"
76+
)))]
5577
impl NoOpRuntime {
5678
/// Creates a new no-op runtime.
5779
pub fn new() -> Self {
@@ -60,17 +82,19 @@ impl NoOpRuntime {
6082
}
6183

6284
// Generates a random jitter value up to max_jitter
63-
#[cfg(any(feature = "experimental-grpc-retry", feature = "experimental-http-retry"))]
85+
#[cfg(any(
86+
feature = "experimental-grpc-retry",
87+
feature = "experimental-http-retry"
88+
))]
6489
fn generate_jitter(max_jitter: u64) -> u64 {
65-
let now = SystemTime::now();
66-
let nanos = now
90+
let nanos = SystemTime::now()
6791
.duration_since(SystemTime::UNIX_EPOCH)
6892
.unwrap()
6993
.subsec_nanos();
7094

71-
let hasher = DefaultHasher::default();
72-
73-
nanos as u64 % (max_jitter + 1)
95+
let mut hasher = DefaultHasher::default();
96+
hasher.write_u32(nanos);
97+
hasher.finish() % (max_jitter + 1)
7498
}
7599

76100
/// Retries the given operation with exponential backoff, jitter, and error classification.
@@ -90,7 +114,10 @@ fn generate_jitter(max_jitter: u64) -> u64 {
90114
///
91115
/// A `Result` containing the operation's result or an error if max retries are reached
92116
/// or a non-retryable error occurs.
93-
#[cfg(any(feature = "experimental-grpc-retry", feature = "experimental-http-retry"))]
117+
#[cfg(any(
118+
feature = "experimental-grpc-retry",
119+
feature = "experimental-http-retry"
120+
))]
94121
pub async fn retry_with_backoff<R, F, Fut, T, E, C>(
95122
runtime: R,
96123
policy: RetryPolicy,
@@ -151,7 +178,10 @@ where
151178

152179
/// No-op retry function for when experimental_async_runtime is not enabled.
153180
/// This function will execute the operation exactly once without any retries.
154-
#[cfg(not(any(feature = "experimental-grpc-retry", feature = "experimental-http-retry")))]
181+
#[cfg(not(any(
182+
feature = "experimental-grpc-retry",
183+
feature = "experimental-http-retry"
184+
)))]
155185
pub async fn retry_with_backoff<R, F, Fut, T, E, C>(
156186
_runtime: R,
157187
_policy: RetryPolicy,

opentelemetry-otlp/src/retry_classification.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,8 +221,8 @@ mod tests {
221221
// Tests for gRPC error classification using public interface
222222
#[cfg(feature = "grpc-tonic")]
223223
mod grpc_tests {
224-
use crate::retry_classification::grpc::classify_tonic_status;
225224
use crate::retry::RetryErrorType;
225+
use crate::retry_classification::grpc::classify_tonic_status;
226226
use tonic_types::{ErrorDetails, StatusExt};
227227

228228
#[test]

opentelemetry-sdk/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,4 +167,3 @@ impl<T> From<std::sync::PoisonError<T>> for InMemoryExporterError {
167167
InMemoryExporterError::InternalFailure(format!("Mutex poison error: {err}"))
168168
}
169169
}
170-

0 commit comments

Comments
 (0)