From 681042539799642cd9616224f169b582e6e5e14d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96rjan=20Fors?= Date: Tue, 9 Jun 2026 16:19:39 +0200 Subject: [PATCH] feat(gax): add jitter knob to RetrySetting Add a jitter knob to RetrySetting but keep it disabled by default. --- .../src/grpc/apiv1/artifact_registry_client.rs | 1 + bigquery/src/grpc/apiv1/bigquery_client.rs | 1 + foundation/gax/Cargo.toml | 2 +- foundation/gax/src/retry.rs | 16 ++++++++++++++-- .../longrunning/src/autogen/operations_client.rs | 1 + kms/src/grpc/apiv1/kms_client.rs | 1 + spanner/src/admin/mod.rs | 1 + spanner/src/apiv1/spanner_client.rs | 1 + 8 files changed, 21 insertions(+), 3 deletions(-) diff --git a/artifact-registry/src/grpc/apiv1/artifact_registry_client.rs b/artifact-registry/src/grpc/apiv1/artifact_registry_client.rs index ff5380fe..a5c9f328 100644 --- a/artifact-registry/src/grpc/apiv1/artifact_registry_client.rs +++ b/artifact-registry/src/grpc/apiv1/artifact_registry_client.rs @@ -27,6 +27,7 @@ fn default_setting() -> RetrySetting { factor: 1u64, take: 20, codes: vec![Code::Unavailable, Code::Unknown], + jitter: false, } } diff --git a/bigquery/src/grpc/apiv1/bigquery_client.rs b/bigquery/src/grpc/apiv1/bigquery_client.rs index 0fce003a..6fef0fab 100644 --- a/bigquery/src/grpc/apiv1/bigquery_client.rs +++ b/bigquery/src/grpc/apiv1/bigquery_client.rs @@ -21,6 +21,7 @@ fn default_setting() -> RetrySetting { factor: 1u64, take: 20, codes: vec![Code::Unavailable, Code::Unknown], + jitter: false, } } diff --git a/foundation/gax/Cargo.toml b/foundation/gax/Cargo.toml index 49960191..01abd5a4 100644 --- a/foundation/gax/Cargo.toml +++ b/foundation/gax/Cargo.toml @@ -20,5 +20,5 @@ thiserror = "2.0" tower = { version = "0.5", features = ["filter", "util"] } http = "1.1" token-source = "1.0" -tokio-retry2 = "0.6" +tokio-retry2 = { version = "0.6", features = ["jitter"] } diff --git a/foundation/gax/src/retry.rs b/foundation/gax/src/retry.rs index dc1b4efe..44995d18 100644 --- a/foundation/gax/src/retry.rs +++ b/foundation/gax/src/retry.rs @@ -3,6 +3,7 @@ use std::iter::Take; use std::time::Duration; pub use tokio_retry2::strategy::ExponentialBackoff; +use tokio_retry2::strategy::jitter; use tokio_retry2::{Action, RetryIf}; pub use tokio_retry2::{Condition, MapErr}; @@ -22,6 +23,9 @@ pub trait Retry, T: Condition> { fn strategy(&self) -> Take; fn condition(&self) -> T; fn notify(error: &E, duration: Duration); + fn jitter(&self) -> bool { + false + } } pub struct CodeCondition { @@ -57,6 +61,7 @@ pub struct RetrySetting { pub factor: u64, pub take: usize, pub codes: Vec, + pub jitter: bool, } impl Retry for RetrySetting { @@ -75,6 +80,10 @@ impl Retry for RetrySetting { fn notify(_error: &Status, _duration: Duration) { tracing::trace!("retry fn"); } + + fn jitter(&self) -> bool { + self.jitter + } } impl Default for RetrySetting { @@ -85,6 +94,7 @@ impl Default for RetrySetting { factor: 1u64, take: 5, codes: vec![Code::Unavailable, Code::Unknown, Code::Aborted], + jitter: false, } } } @@ -97,7 +107,8 @@ where RT: Retry + Default, { let retry = retry.unwrap_or_default(); - RetryIf::spawn(retry.strategy(), action, retry.condition(), RT::notify).await + let apply: fn(Duration) -> Duration = if retry.jitter() { jitter } else { |d| d }; + RetryIf::spawn(retry.strategy().map(apply), action, retry.condition(), RT::notify).await } /// Repeats retries when the specified error is detected. /// The argument specified by 'v' can be reused for each retry. @@ -109,7 +120,8 @@ where RT: Retry + Default, { let retry = retry.unwrap_or_default(); - let mut strategy = retry.strategy(); + let apply: fn(Duration) -> Duration = if retry.jitter() { jitter } else { |d| d }; + let mut strategy = retry.strategy().map(apply); loop { let result = f(v).await; let status = match result { diff --git a/foundation/longrunning/src/autogen/operations_client.rs b/foundation/longrunning/src/autogen/operations_client.rs index eb4947bb..98579c8b 100644 --- a/foundation/longrunning/src/autogen/operations_client.rs +++ b/foundation/longrunning/src/autogen/operations_client.rs @@ -18,6 +18,7 @@ pub fn default_retry_setting() -> RetrySetting { factor: 1u64, take: 20, codes: vec![Code::Unavailable, Code::Unknown], + jitter: false, } } diff --git a/kms/src/grpc/apiv1/kms_client.rs b/kms/src/grpc/apiv1/kms_client.rs index 55b56e48..01f95915 100644 --- a/kms/src/grpc/apiv1/kms_client.rs +++ b/kms/src/grpc/apiv1/kms_client.rs @@ -37,6 +37,7 @@ fn default_setting() -> RetrySetting { factor: 1u64, take: 20, codes: vec![Code::Unavailable, Code::Unknown], + jitter: false, } } diff --git a/spanner/src/admin/mod.rs b/spanner/src/admin/mod.rs index 1f44ec19..3f311310 100644 --- a/spanner/src/admin/mod.rs +++ b/spanner/src/admin/mod.rs @@ -85,5 +85,6 @@ pub fn default_retry_setting() -> RetrySetting { factor: 1u64, take: 20, codes: vec![Code::Unavailable, Code::Unknown, Code::DeadlineExceeded], + jitter: false, } } diff --git a/spanner/src/apiv1/spanner_client.rs b/spanner/src/apiv1/spanner_client.rs index 3f35013d..9e43a025 100644 --- a/spanner/src/apiv1/spanner_client.rs +++ b/spanner/src/apiv1/spanner_client.rs @@ -44,6 +44,7 @@ fn default_setting() -> RetrySetting { factor: 1u64, take: 20, codes: vec![Code::Unavailable, Code::Unknown], + jitter: false, } }