From 5b0158f02c49159717c6fb7fd8f8aa8d2a89f759 Mon Sep 17 00:00:00 2001 From: Ragnar Date: Tue, 21 Jan 2025 03:43:25 +0100 Subject: [PATCH] Update http_rpc.rs --- core/src/execution/rpc/http_rpc.rs | 64 ++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/core/src/execution/rpc/http_rpc.rs b/core/src/execution/rpc/http_rpc.rs index 9b175695..6bcd7b02 100644 --- a/core/src/execution/rpc/http_rpc.rs +++ b/core/src/execution/rpc/http_rpc.rs @@ -231,3 +231,67 @@ impl ExecutionRpc for HttpRpc { .ok_or(eyre!("block not found")) } } + +#[cfg(target_arch = "wasm32")] +use std::time::Duration; +#[cfg(target_arch = "wasm32")] +use wasmtimer::tokio::sleep; + +#[cfg(target_arch = "wasm32")] +#[derive(Clone, Debug)] +struct RetryConfig { + max_attempts: u32, + initial_backoff: Duration, + max_backoff: Duration, +} + +#[cfg(target_arch = "wasm32")] +impl Default for RetryConfig { + fn default() -> Self { + Self { + max_attempts: 3, + initial_backoff: Duration::from_millis(100), + max_backoff: Duration::from_secs(5), + } + } +} + +#[cfg(target_arch = "wasm32")] +impl HttpRpc { + async fn execute_with_retry(&self, operation: F) -> Result + where + F: Fn() -> Fut + Clone, + Fut: std::future::Future>, + { + let config = RetryConfig::default(); + let mut attempts = 0; + let mut backoff = config.initial_backoff; + + loop { + attempts += 1; + match operation().await { + Ok(response) => return Ok(response), + Err(err) => { + if !Self::should_retry(&err) || attempts >= config.max_attempts { + return Err(err); + } + + sleep(backoff).await; + backoff = std::cmp::min(backoff * 2, config.max_backoff); + } + } + } + } + + fn should_retry(err: &RpcError) -> bool { + if let Some(source) = &err.source { + let error_str = source.to_string().to_lowercase(); + error_str.contains("rate limit") || + error_str.contains("timeout") || + error_str.contains("connection") || + (error_str.contains("server") && error_str.contains("50")) + } else { + false + } + } +}