From 4cfcd5117f3d439b322ad9d490f105ced0c667c0 Mon Sep 17 00:00:00 2001 From: Siavash Sameni Date: Sun, 12 Apr 2026 13:06:13 +0400 Subject: [PATCH] fix(connect): install MediaPathReport oneshot BEFORE race starts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The peer's MediaPathReport can arrive while our dual_path::race is still running. Previously, the oneshot was created AFTER the race completed, so the recv loop had nowhere to deliver the report — it was silently dropped, causing a 3s timeout and false relay fallback on ~50% of calls. Fix: create the oneshot and install it in SignalState BEFORE starting the race. The oneshot::Receiver buffers the value so the connect command can read it immediately after the race finishes. Co-Authored-By: Claude Opus 4.6 (1M context) --- desktop/src-tauri/src/lib.rs | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/desktop/src-tauri/src/lib.rs b/desktop/src-tauri/src/lib.rs index b2a97e4..02fc7ce 100644 --- a/desktop/src-tauri/src/lib.rs +++ b/desktop/src-tauri/src/lib.rs @@ -415,6 +415,18 @@ async fn connect( "relay_addr": relay_sockaddr.to_string(), "own_reflex_addr": own_reflex_addr, })); + // Phase 6 fix: install the oneshot BEFORE the race + // starts. The peer's MediaPathReport can arrive + // while our race is still running — if we set up + // the oneshot after the race, the recv loop has + // nowhere to send the report and it gets dropped, + // causing a 3s timeout and false relay fallback. + let (path_report_tx, path_report_rx) = tokio::sync::oneshot::channel::(); + { + let mut sig = state.signal.lock().await; + sig.pending_path_report = Some(path_report_tx); + } + let room_sni = room.clone(); let call_sni = format!("call-{room}"); match wzp_client::dual_path::race( @@ -456,12 +468,14 @@ async fn connect( .unwrap_or(&room) .to_string(); - // Install the oneshot for receiving the peer's report - let (tx, rx) = tokio::sync::oneshot::channel::(); + // The oneshot was installed BEFORE the race + // (see path_report_tx above) so the peer's + // report is already buffered in path_report_rx + // if it arrived during the race. + let rx = path_report_rx; let peer_direct_ok = { let transport_for_report = { - let mut sig = state.signal.lock().await; - sig.pending_path_report = Some(tx); + let sig = state.signal.lock().await; sig.transport.as_ref().cloned() }; // Send our report