diff --git a/src-tauri/src/poller.rs b/src-tauri/src/poller.rs index ed0908a..e5d7189 100644 --- a/src-tauri/src/poller.rs +++ b/src-tauri/src/poller.rs @@ -11,7 +11,7 @@ use tracing::warn; const PEERS_INTERVAL: Duration = Duration::from_secs(3); const ROUTES_INTERVAL: Duration = Duration::from_secs(5); -const INBOX_LONG_POLL_SECS: u64 = 30; +const INBOX_INTERVAL: Duration = Duration::from_secs(2); const INBOX_RETRY_BACKOFF: Duration = Duration::from_secs(2); const INBOX_CAPACITY: usize = 200; @@ -121,18 +121,22 @@ fn spawn_inbox_loop( ) -> JoinHandle<()> { tokio::spawn(async move { loop { + tokio::time::sleep(INBOX_INTERVAL).await; let Some(client) = sidecar.client() else { break; }; - // Each iteration is a fresh long-poll. The daemon answers as - // soon as a message arrives, or returns an empty body / 204 - // when the timeout window elapses. - match client.pop_message(false, INBOX_LONG_POLL_SECS, None).await { + // Short-poll: timeout=0 returns immediately if no message. + // We previously used a 30s long-poll, but mycelium 0.6.1's + // HTTP server appears to serialise requests behind a single + // worker — holding the connection for 30s starved every + // other endpoint (peers, routes, admin) until our own + // 10s reqwest timeout kicked in. + match client.pop_message(false, 0, None).await { Ok(Some(msg)) => { me.push_inbox(msg.clone()); let _ = app.emit("messages://incoming", &msg); } - Ok(None) => {} // window expired, loop + Ok(None) => {} Err(e) => { warn!(error = %e, "inbox: pop_message failed"); tokio::time::sleep(INBOX_RETRY_BACKOFF).await;