fix(relay): debug tap signal logging, dual_path test regression, PRD updates
Some checks failed
Build Release Binaries / build-amd64 (push) Failing after 3m39s
Mirror to GitHub / mirror (push) Failing after 28s

- Add log_signal() and log_event() to DebugTap for RoomUpdate,
  QualityDirective, join/leave lifecycle events (task #11)
- Fix dual_path.rs Phase 7 regression: add missing ipv6_endpoint arg
  to 3 race() call sites
- Update PRDs to reflect actual implementation status: mark adaptive
  quality, coordinated codec, P2P, network awareness, protocol analyzer
- Update PROGRESS.md with QualityDirective gap and dual_path regression

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Siavash Sameni
2026-04-13 09:54:52 +04:00
parent 1a7dd935ee
commit ea5fc17c34
9 changed files with 131 additions and 19 deletions

View File

@@ -118,6 +118,7 @@ async fn dual_path_direct_wins_on_loopback() {
"test-room".into(),
"call-test".into(),
None, // Phase 5: tests use fresh endpoints (no shared signal)
None, // Phase 7: no IPv6 endpoint in tests
)
.await
.expect("race must succeed");
@@ -160,6 +161,7 @@ async fn dual_path_relay_wins_when_direct_is_dead() {
"test-room".into(),
"call-test".into(),
None, // Phase 5: tests use fresh endpoints (no shared signal)
None, // Phase 7: no IPv6 endpoint in tests
)
.await
.expect("race must succeed via relay fallback");
@@ -198,6 +200,7 @@ async fn dual_path_errors_cleanly_when_both_paths_dead() {
"test-room".into(),
"call-test".into(),
None, // Phase 5: tests use fresh endpoints (no shared signal)
None, // Phase 7: no IPv6 endpoint in tests
)
.await;
let elapsed = start.elapsed();

View File

@@ -509,7 +509,7 @@ async fn main() -> anyhow::Result<()> {
}
}
if let Some(ref tap) = config.debug_tap {
info!(filter = %tap, "debug tap enabled — logging packet headers");
info!(filter = %tap, "debug tap enabled — logging packets, signals, join/leave events");
}
// Phase 4: cross-relay direct-call dispatcher task.
@@ -1663,6 +1663,15 @@ async fn main() -> anyhow::Result<()> {
} else { update }
} else { update };
if let Some(ref tap) = debug_tap {
if tap.matches(&room_name) {
tap.log_signal(&room_name, &merged_update);
tap.log_event(&room_name, "join", &format!(
"participant={id} addr={addr} alias={}",
caller_alias.as_deref().unwrap_or("?")
));
}
}
room::broadcast_signal(&senders, &merged_update).await;
id
}

View File

@@ -50,6 +50,52 @@ impl DebugTap {
"TAP"
);
}
pub fn log_signal(&self, room: &str, signal: &wzp_proto::SignalMessage) {
match signal {
wzp_proto::SignalMessage::RoomUpdate { count, participants } => {
let names: Vec<&str> = participants.iter()
.map(|p| p.alias.as_deref().unwrap_or("?"))
.collect();
info!(
target: "debug_tap",
room = %room,
signal = "RoomUpdate",
count,
participants = ?names,
"TAP SIGNAL"
);
}
wzp_proto::SignalMessage::QualityDirective { recommended_profile, reason } => {
info!(
target: "debug_tap",
room = %room,
signal = "QualityDirective",
codec = ?recommended_profile.codec,
reason = reason.as_deref().unwrap_or(""),
"TAP SIGNAL"
);
}
other => {
info!(
target: "debug_tap",
room = %room,
signal = ?std::mem::discriminant(other),
"TAP SIGNAL"
);
}
}
}
pub fn log_event(&self, room: &str, event: &str, detail: &str) {
info!(
target: "debug_tap",
room = %room,
event,
detail,
"TAP EVENT"
);
}
}
/// Tracks network quality for a single participant in a room.
@@ -663,6 +709,11 @@ async fn run_participant_plain(
// Broadcast quality directive to all participants if tier changed
if let Some((directive, all_senders)) = quality_directive {
if let Some(ref tap) = debug_tap {
if tap.matches(&room_name) {
tap.log_signal(&room_name, &directive);
}
}
broadcast_signal(&all_senders, &directive).await;
}
@@ -754,7 +805,21 @@ async fn run_participant_plain(
let mut mgr = room_mgr.lock().await;
if let Some((update, senders)) = mgr.leave(&room_name, participant_id) {
drop(mgr); // release lock before async broadcast
if let Some(ref tap) = debug_tap {
if tap.matches(&room_name) {
tap.log_event(&room_name, "leave", &format!(
"participant={participant_id} addr={addr} forwarded={packets_forwarded}"
));
tap.log_signal(&room_name, &update);
}
}
broadcast_signal(&senders, &update).await;
} else if let Some(ref tap) = debug_tap {
if tap.matches(&room_name) {
tap.log_event(&room_name, "leave", &format!(
"participant={participant_id} addr={addr} (room closed)"
));
}
}
}