From 2e84fc673798e5ab1e0ffc19f496598bec7d15e5 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 6 Oct 2022 14:20:40 +0200 Subject: [PATCH] Delete rooms without pending users or participants --- crates/collab/src/integration_tests.rs | 21 +++++++++++++++++++++ crates/collab/src/rpc.rs | 4 +++- crates/collab/src/rpc/store.rs | 23 ++++++++++++++++++----- 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/crates/collab/src/integration_tests.rs b/crates/collab/src/integration_tests.rs index 1adac8b28e..a11d908cdd 100644 --- a/crates/collab/src/integration_tests.rs +++ b/crates/collab/src/integration_tests.rs @@ -203,6 +203,27 @@ async fn test_basic_calls( pending: Default::default() } ); + + // User B leaves the room. + active_call_b.update(cx_b, |call, cx| { + call.hang_up(cx).unwrap(); + assert!(call.room().is_none()); + }); + deterministic.run_until_parked(); + assert_eq!( + room_participants(&room_a, cx_a), + RoomParticipants { + remote: Default::default(), + pending: Default::default() + } + ); + assert_eq!( + room_participants(&room_b, cx_b), + RoomParticipants { + remote: Default::default(), + pending: Default::default() + } + ); } #[gpui::test(iterations = 10)] diff --git a/crates/collab/src/rpc.rs b/crates/collab/src/rpc.rs index 4098e6522a..46bf4bf3dc 100644 --- a/crates/collab/src/rpc.rs +++ b/crates/collab/src/rpc.rs @@ -646,7 +646,9 @@ impl Server { } } - self.room_updated(left_room.room); + if let Some(room) = left_room.room { + self.room_updated(room); + } Ok(()) } diff --git a/crates/collab/src/rpc/store.rs b/crates/collab/src/rpc/store.rs index 2f95851bf7..a0d272ccc8 100644 --- a/crates/collab/src/rpc/store.rs +++ b/crates/collab/src/rpc/store.rs @@ -101,7 +101,7 @@ pub struct LeftProject { } pub struct LeftRoom<'a> { - pub room: &'a proto::Room, + pub room: Option<&'a proto::Room>, pub unshared_projects: Vec, pub left_projects: Vec, } @@ -222,7 +222,8 @@ impl Store { let connected_user = self.connected_users.get_mut(&user_id).unwrap(); connected_user.connection_ids.remove(&connection_id); if let Some(active_call) = connected_user.active_call.as_ref() { - if let Some(room) = self.rooms.get_mut(&active_call.room_id) { + let room_id = active_call.room_id; + if let Some(room) = self.rooms.get_mut(&room_id) { let prev_participant_count = room.participants.len(); room.participants .retain(|participant| participant.peer_id != connection_id.0); @@ -230,13 +231,17 @@ impl Store { if connected_user.connection_ids.is_empty() { room.pending_user_ids .retain(|pending_user_id| *pending_user_id != user_id.to_proto()); - result.room_id = Some(active_call.room_id); + result.room_id = Some(room_id); connected_user.active_call = None; } } else { - result.room_id = Some(active_call.room_id); + result.room_id = Some(room_id); connected_user.active_call = None; } + + if room.participants.is_empty() && room.pending_user_ids.is_empty() { + self.rooms.remove(&room_id); + } } else { tracing::error!("disconnected user claims to be in a room that does not exist"); connected_user.active_call = None; @@ -476,9 +481,12 @@ impl Store { .ok_or_else(|| anyhow!("no such room"))?; room.participants .retain(|participant| participant.peer_id != connection_id.0); + if room.participants.is_empty() && room.pending_user_ids.is_empty() { + self.rooms.remove(&room_id); + } Ok(LeftRoom { - room, + room: self.rooms.get(&room_id), unshared_projects, left_projects, }) @@ -1069,6 +1077,11 @@ impl Store { ); } } + + assert!( + !room.pending_user_ids.is_empty() || !room.participants.is_empty(), + "room can't be empty" + ); } for (project_id, project) in &self.projects {