diff --git a/src/channels/feishu.rs b/src/channels/feishu.rs index 0b856a4..09b56bc 100644 --- a/src/channels/feishu.rs +++ b/src/channels/feishu.rs @@ -2308,8 +2308,9 @@ impl Channel for FeishuChannel { let channel = self.clone(); let bus = bus.clone(); tokio::spawn(async move { - let mut consecutive_failures = 0; - let max_failures = 3; + let mut consecutive_failures: u32 = 0; + let base_retry_secs: u64 = 5; + let max_retry_secs: u64 = 60; loop { if !*channel.running.read().await { @@ -2319,15 +2320,12 @@ impl Channel for FeishuChannel { let shutdown_rx = shutdown_tx.subscribe(); match channel.run_ws_loop(bus.clone(), shutdown_rx).await { Ok(_) => { + consecutive_failures = 0; tracing::info!("Feishu WebSocket disconnected"); } Err(e) => { - consecutive_failures += 1; + consecutive_failures = consecutive_failures.saturating_add(1); tracing::error!(attempt = consecutive_failures, error = %e, "Feishu WebSocket error"); - if consecutive_failures >= max_failures { - tracing::error!("Feishu channel: max failures reached, stopping"); - break; - } } } @@ -2335,8 +2333,15 @@ impl Channel for FeishuChannel { break; } - tracing::info!("Feishu channel retrying in 5s..."); - tokio::time::sleep(tokio::time::Duration::from_secs(5)).await; + let exponent = consecutive_failures.saturating_sub(1).min(6); + let retry_secs = (base_retry_secs * (1u64 << exponent)).min(max_retry_secs); + tracing::info!("Feishu channel retrying in {}s...", retry_secs); + let mut remaining = retry_secs; + while remaining > 0 && *channel.running.read().await { + let step = remaining.min(base_retry_secs); + tokio::time::sleep(tokio::time::Duration::from_secs(step)).await; + remaining -= step; + } } *channel.running.write().await = false;