server usb cycle update

This commit is contained in:
Brad Stein 2025-06-25 21:15:24 -05:00
parent c806faba6f
commit d4261c8383
2 changed files with 13 additions and 28 deletions

View File

@ -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

View File

@ -50,13 +50,9 @@ fn init_tracing() -> anyhow::Result<WorkerGuard> {
Ok(guard)
}
async fn open_with_retry(
path: &str,
retries: usize,
base_delay_ms: u64,
) -> anyhow::Result<tokio::fs::File> {
let start = std::time::Instant::now();
for attempt in 0..=retries {
async fn open_with_retry(path: &str) -> anyhow::Result<tokio::fs::File> {
const MAX_ATTEMPTS: usize = 40; // ≈ 2s (@50ms)
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 {