From 28f4a0fb6fa2b5873d27c81f18bd35283d2fe4dd Mon Sep 17 00:00:00 2001 From: Siavash Sameni Date: Wed, 8 Apr 2026 13:43:15 +0400 Subject: [PATCH] =?UTF-8?q?fix:=20multi-hop=20presence=20=E2=80=94=20propa?= =?UTF-8?q?gate=20remote=20rooms=20on=20new=20peer=20connect?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a new federation link is established, announce not only LOCAL global rooms but also rooms from OTHER peers (remote_participants). This fixes multi-hop: when R2 connects to R3, R2 tells R3 about R1's rooms that R2 learned about earlier. Previously, only local rooms were announced on link setup. If R1 had a client but R2 had no clients, R2 wouldn't tell R3 about R1. Also added diagnostic logging for room announcements on link setup. Co-Authored-By: Claude Opus 4.6 (1M context) --- crates/wzp-relay/src/federation.rs | 39 ++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/crates/wzp-relay/src/federation.rs b/crates/wzp-relay/src/federation.rs index 58f4dfa..8e4e4d4 100644 --- a/crates/wzp-relay/src/federation.rs +++ b/crates/wzp-relay/src/federation.rs @@ -436,16 +436,41 @@ async fn run_federation_link( }); } - // Announce our currently active global rooms - { + // Announce our currently active global rooms to this new peer + // Collect all announcements first, then send (avoid holding locks across await) + let announcements = { let mgr = fm.room_mgr.lock().await; - for room_name in mgr.active_rooms() { - if fm.is_global_room(&room_name) { - let participants = mgr.local_participant_list(&room_name); - let msg = SignalMessage::GlobalRoomActive { room: room_name, participants }; - let _ = transport.send_signal(&msg).await; + let active = mgr.active_rooms(); + let mut msgs = Vec::new(); + + // Local rooms + for room_name in &active { + if fm.is_global_room(room_name) { + let participants = mgr.local_participant_list(room_name); + info!(peer = %peer_label, room = %room_name, participants = participants.len(), "announcing local global room to new peer"); + msgs.push(SignalMessage::GlobalRoomActive { room: room_name.clone(), participants }); } } + + // Remote rooms from OTHER peers (for multi-hop propagation) + let links = fm.peer_links.lock().await; + for (fp, link) in links.iter() { + if fp != &peer_fp { + for (room, participants) in &link.remote_participants { + if fm.is_global_room(room) { + info!(peer = %peer_label, room = %room, via = %link.label, "propagating remote room to new peer"); + msgs.push(SignalMessage::GlobalRoomActive { + room: room.clone(), + participants: participants.clone(), + }); + } + } + } + } + msgs + }; + for msg in &announcements { + let _ = transport.send_signal(msg).await; } // Three concurrent tasks: signal recv + media recv + RTT monitor