From d4261c838382f36e3b848696911058758dce1b36 Mon Sep 17 00:00:00 2001 From: Brad Stein Date: Wed, 25 Jun 2025 21:15:24 -0500 Subject: [PATCH] server usb cycle update --- scripts/install-server.sh | 3 ++- server/src/main.rs | 38 +++++++++++--------------------------- 2 files changed, 13 insertions(+), 28 deletions(-) diff --git a/scripts/install-server.sh b/scripts/install-server.sh index 1edd07f..dcfce63 100755 --- a/scripts/install-server.sh +++ b/scripts/install-server.sh @@ -107,7 +107,8 @@ Restart=always Environment=RUST_LOG=lesavka_server=debug,lesavka_server::usb_gadget=trace Environment=RUST_BACKTRACE=1 Restart=always -RestartSec=2 +RestartSec=3 +StandardError=append:/tmp/lesavka-server.log StartLimitIntervalSec=30 StartLimitBurst=10 User=root diff --git a/server/src/main.rs b/server/src/main.rs index e91f23c..733afcc 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -50,13 +50,9 @@ fn init_tracing() -> anyhow::Result { Ok(guard) } -async fn open_with_retry( - path: &str, - retries: usize, - base_delay_ms: u64, -) -> anyhow::Result { - let start = std::time::Instant::now(); - for attempt in 0..=retries { +async fn open_with_retry(path: &str) -> anyhow::Result { + const MAX_ATTEMPTS: usize = 40; // ≈ 2 s (@50 ms) + for attempt in 1..=MAX_ATTEMPTS { match OpenOptions::new() .write(true) .custom_flags(libc::O_NONBLOCK) @@ -64,29 +60,17 @@ async fn open_with_retry( .await { Ok(f) => { - info!("✅ opened {path} (attempt {attempt}, {} ms)", - start.elapsed().as_millis()); + info!("✅ {path} opened on attempt #{attempt}"); return Ok(f); } - Err(e) if attempt < retries => { - let delay = base_delay_ms * 2u64.saturating_pow(attempt as u32); - warn!( - "🕒 {path} busy: {e:?}; holders=[{}]; retry {attempt}/{retries} in {delay} ms", - owners_of(path) - ); - tokio::time::sleep(Duration::from_millis(delay)).await; - } - Err(e) => { - error!( - "💥 all retries exhausted for {path} ({} ms): {e:?}; holders=[{}]", - start.elapsed().as_millis(), - owners_of(path) - ); - return Err(e).with_context(|| format!("opening {path}")); + Err(e) if e.kind() == std::io::ErrorKind::Other /* EBUSY */ => { + trace!("⏳ {path} busy, retry #{attempt}"); + tokio::time::sleep(Duration::from_millis(50)).await; } + Err(e) => return Err(e).with_context(|| format!("💥 opening {path}")), } } - unreachable!() + Err(anyhow::anyhow!("💥 timeout waiting for {path} to become available")) } fn owners_of(path: &str) -> String { @@ -130,8 +114,8 @@ impl Handler { tokio::time::sleep(Duration::from_millis(1000)).await; info!("🛠️ opening HID endpoints ..."); - let kb = open_with_retry("/dev/hidg0", 20, 50).await?; - let ms = open_with_retry("/dev/hidg1", 20, 50).await?; + let kb = open_with_retry("/dev/hidg0").await?; + let ms = open_with_retry("/dev/hidg1").await?; info!("✅ HID endpoints ready"); Ok(Self {