MCPcopy Create free account
hub / github.com/NVIDIA/OpenShell / grpc_retry

Function grpc_retry

crates/openshell-sandbox/src/lib.rs:1319–1350  ·  view source on GitHub ↗

Retry a gRPC operation with exponential backoff (capped at 4 s). Non-transient gRPC errors (e.g. `NOT_FOUND`, `INVALID_ARGUMENT`, `PERMISSION_DENIED`) are returned immediately without retrying.

(op_name: &str, f: F)

Source from the content-addressed store, hash-verified

1317/// Non-transient gRPC errors (e.g. `NOT_FOUND`, `INVALID_ARGUMENT`,
1318/// `PERMISSION_DENIED`) are returned immediately without retrying.
1319async fn grpc_retry<T, F, Fut>(op_name: &str, f: F) -> Result<T>
1320where
1321 F: Fn() -> Fut,
1322 Fut: Future<Output = Result<T>>,
1323{
1324 let mut last_err = None;
1325 for attempt in 1..=5u32 {
1326 match f().await {
1327 Ok(val) => return Ok(val),
1328 Err(e) => {
1329 if !is_retryable_error(&e) {
1330 return Err(e);
1331 }
1332 if attempt < 5 {
1333 warn!(
1334 attempt,
1335 max_attempts = 5,
1336 error = %e,
1337 "{op_name} failed, retrying"
1338 );
1339 let backoff = Duration::from_secs((1u64 << (attempt - 1)).min(4));
1340 tokio::time::sleep(backoff).await;
1341 }
1342 last_err = Some(e);
1343 }
1344 }
1345 }
1346 Err(miette::miette!(
1347 "{op_name} failed after 5 attempts: {}",
1348 last_err.expect("loop executed at least once")
1349 ))
1350}
1351
1352/// Load sandbox policy from local files or gRPC.
1353///

Callers 1

load_policyFunction · 0.85

Calls 1

is_retryable_errorFunction · 0.85

Tested by

no test coverage detected