From dc8559f7640d16e8f2bd7d11be86b70b3de613e6 Mon Sep 17 00:00:00 2001 From: Brad Stein Date: Fri, 1 May 2026 16:31:17 -0300 Subject: [PATCH] sync: keep microphone uplink freshness-first --- AGENTS.md | 1 + Cargo.lock | 6 +++--- client/Cargo.toml | 2 +- client/src/app/uplink_media.rs | 2 +- client/src/sync_probe/capture.rs | 2 +- common/Cargo.toml | 2 +- server/Cargo.toml | 2 +- testing/tests/client_uplink_freshness_contract.rs | 13 ++++++++++++- 8 files changed, 21 insertions(+), 9 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index ab5ac2b..a72ea5e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -175,5 +175,6 @@ Context: the mirrored browser probe finally reproduced the real failure class on - 0.16.22 live mirrored run still failed with p95 `433.7 ms`, median `-359.4 ms`, and 5 paired coded pulses. Client telemetry showed camera uplink `latest_age_ms` repeatedly around `300-350 ms`, matching the measured skew; patch 0.16.23 to make video queues latest-only instead of draining stale-but-under-budget backlog. - 0.16.23 local validation passed for fresh-queue behavior, uplink/probe freshness contracts, sync analyzer tests, client/server binary checks, and whitespace checks. - 0.16.23 live mirrored run improved to p95 `215.2 ms`, median `+142.2 ms`, 13 paired coded pulses, and raw activity alignment within `6.6 ms` of coded pairs. Patch 0.16.24 makes the probe print local client and remote server versions before capture so every run records what was actually tested. + - 0.16.24 live mirrored run improved again to p95 `168.4 ms`, median `-19.1 ms`, 11 paired coded pulses, but still failed because individual paired pulses bounced between about `-168 ms` and `+45 ms`. Client logs showed the microphone uplink queue still accumulating depth `16`; patch 0.16.25 makes microphone uplink queues latest-only too so stale audio PTS cannot continue acting as the server timing master under backpressure. - [ ] Re-run the mirrored browser probe after the pre-start false-positive fix. - [ ] Run Google Meet manual validation. diff --git a/Cargo.lock b/Cargo.lock index 19322dd..cf202ca 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1652,7 +1652,7 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "lesavka_client" -version = "0.16.24" +version = "0.16.25" dependencies = [ "anyhow", "async-stream", @@ -1686,7 +1686,7 @@ dependencies = [ [[package]] name = "lesavka_common" -version = "0.16.24" +version = "0.16.25" dependencies = [ "anyhow", "base64", @@ -1698,7 +1698,7 @@ dependencies = [ [[package]] name = "lesavka_server" -version = "0.16.24" +version = "0.16.25" dependencies = [ "anyhow", "base64", diff --git a/client/Cargo.toml b/client/Cargo.toml index a163349..aa6297a 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -4,7 +4,7 @@ path = "src/main.rs" [package] name = "lesavka_client" -version = "0.16.24" +version = "0.16.25" edition = "2024" [dependencies] diff --git a/client/src/app/uplink_media.rs b/client/src/app/uplink_media.rs index 2a9b979..1a55e8d 100644 --- a/client/src/app/uplink_media.rs +++ b/client/src/app/uplink_media.rs @@ -261,7 +261,7 @@ const AUDIO_UPLINK_QUEUE: crate::uplink_fresh_queue::FreshQueueConfig = crate::uplink_fresh_queue::FreshQueueConfig { capacity: 16, max_age: Duration::from_millis(400), - policy: crate::uplink_fresh_queue::FreshQueuePolicy::DrainOldest, + policy: crate::uplink_fresh_queue::FreshQueuePolicy::LatestOnly, }; #[cfg(not(coverage))] diff --git a/client/src/sync_probe/capture.rs b/client/src/sync_probe/capture.rs index f2d1dc5..e750248 100644 --- a/client/src/sync_probe/capture.rs +++ b/client/src/sync_probe/capture.rs @@ -52,7 +52,7 @@ const PROBE_VIDEO_QUEUE: FreshQueueConfig = FreshQueueConfig { const PROBE_AUDIO_QUEUE: FreshQueueConfig = FreshQueueConfig { capacity: 32, max_age: Duration::from_millis(400), - policy: crate::uplink_fresh_queue::FreshQueuePolicy::DrainOldest, + policy: crate::uplink_fresh_queue::FreshQueuePolicy::LatestOnly, }; #[cfg(any(not(coverage), test))] diff --git a/common/Cargo.toml b/common/Cargo.toml index a0a4098..40b43b5 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "lesavka_common" -version = "0.16.24" +version = "0.16.25" edition = "2024" build = "build.rs" diff --git a/server/Cargo.toml b/server/Cargo.toml index 2bb5b5c..ab42874 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -10,7 +10,7 @@ bench = false [package] name = "lesavka_server" -version = "0.16.24" +version = "0.16.25" edition = "2024" autobins = false diff --git a/testing/tests/client_uplink_freshness_contract.rs b/testing/tests/client_uplink_freshness_contract.rs index a192eb4..222dd64 100644 --- a/testing/tests/client_uplink_freshness_contract.rs +++ b/testing/tests/client_uplink_freshness_contract.rs @@ -82,7 +82,7 @@ fn microphone_uplink_queue_freshness_budget_stays_within_live_audio_window() { max_age_ms <= 400, "AUDIO_UPLINK_QUEUE max_age is {max_age_ms}ms; keep it <= 400ms for live calls" ); - assert_queue_policy(block, "AUDIO_UPLINK_QUEUE", "DrainOldest"); + assert_queue_policy(block, "AUDIO_UPLINK_QUEUE", "LatestOnly"); } #[test] @@ -105,3 +105,14 @@ fn sync_probe_video_queue_uses_same_freshness_budget() { ); assert_queue_policy(block, "PROBE_VIDEO_QUEUE", "LatestOnly"); } + +#[test] +fn sync_probe_audio_queue_uses_live_latest_only_policy() { + let block = queue_block(SYNC_PROBE_CAPTURE_SRC, "PROBE_AUDIO_QUEUE"); + let max_age_ms = parse_queue_max_age_ms(block, "PROBE_AUDIO_QUEUE"); + assert!( + max_age_ms <= 400, + "PROBE_AUDIO_QUEUE max_age is {max_age_ms}ms; keep probe audio from preserving stale timing anchors" + ); + assert_queue_policy(block, "PROBE_AUDIO_QUEUE", "LatestOnly"); +}