fix: survive QUIC congestion — drop packets instead of killing send task
Some checks failed
Build Release Binaries / build-amd64 (push) Failing after 3m14s
Some checks failed
Build Release Binaries / build-amd64 (push) Failing after 3m14s
send_datagram() returns Err(Blocked) when the QUIC congestion window is full. This is transient — the window reopens once ACKs arrive. Previously, all send paths treated this as fatal (break/return), which killed the send task and cascaded via tokio::select! to kill the entire call. Now: log warning, drop the packet, continue. Brief audio glitch (20-100ms) instead of complete call death. FEC on the receiver side recovers most dropped packets. Fixed in: - CLI run_live send task (continue + error counter) - CLI run_file_mode send paths (2 locations) - Desktop engine send task Also hardened recv tasks: transient errors (non-closed/reset) are survived instead of causing exit. Matches the fix applied to Android client (engine.rs). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -171,6 +171,7 @@ impl CallEngine {
|
||||
let send_mic = mic_muted.clone();
|
||||
let send_fs = frames_sent.clone();
|
||||
let send_level = audio_level.clone();
|
||||
let send_drops = Arc::new(AtomicU64::new(0));
|
||||
tokio::spawn(async move {
|
||||
let config = CallConfig {
|
||||
noise_suppression: false,
|
||||
@@ -205,8 +206,11 @@ impl CallEngine {
|
||||
Ok(pkts) => {
|
||||
for pkt in &pkts {
|
||||
if let Err(e) = send_t.send_media(pkt).await {
|
||||
error!("send: {e}");
|
||||
return;
|
||||
// Transient congestion (Blocked) — drop packet, keep going
|
||||
send_drops.fetch_add(1, Ordering::Relaxed);
|
||||
if send_drops.load(Ordering::Relaxed) <= 3 {
|
||||
tracing::warn!("send_media error (dropping packet): {e}");
|
||||
}
|
||||
}
|
||||
}
|
||||
send_fs.fetch_add(1, Ordering::Relaxed);
|
||||
@@ -249,8 +253,12 @@ impl CallEngine {
|
||||
}
|
||||
Ok(Ok(None)) => break,
|
||||
Ok(Err(e)) => {
|
||||
error!("recv: {e}");
|
||||
break;
|
||||
let msg = e.to_string();
|
||||
if msg.contains("closed") || msg.contains("reset") {
|
||||
error!("recv fatal: {e}");
|
||||
break;
|
||||
}
|
||||
// Transient error — continue
|
||||
}
|
||||
Err(_) => {}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user