From bbeb33bc7e88a16aee9fa011ff05c1687a1b0a0b Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 23 Feb 2023 15:54:35 +0100 Subject: [PATCH] Fix error when deleting rooms containing projects on refresh A foreign key violation was causing the server to never delete stale rooms during `Database::refresh_room` due to having one or more project records referencing the room. --- crates/collab/src/db.rs | 4 ++++ crates/collab/src/rpc.rs | 7 +++++-- crates/collab/src/tests/integration_tests.rs | 14 +++++++++++--- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/crates/collab/src/db.rs b/crates/collab/src/db.rs index a2939bf9ae..d7e67b5834 100644 --- a/crates/collab/src/db.rs +++ b/crates/collab/src/db.rs @@ -191,6 +191,10 @@ impl Database { .filter(room_participant::Column::RoomId.eq(room_id)) .exec(&*tx) .await?; + project::Entity::delete_many() + .filter(project::Column::RoomId.eq(room_id)) + .exec(&*tx) + .await?; room::Entity::delete_by_id(room_id).exec(&*tx).await?; } diff --git a/crates/collab/src/rpc.rs b/crates/collab/src/rpc.rs index dbfdf74865..01d24024eb 100644 --- a/crates/collab/src/rpc.rs +++ b/crates/collab/src/rpc.rs @@ -270,8 +270,11 @@ impl Server { let mut live_kit_room = String::new(); let mut delete_live_kit_room = false; - if let Ok(mut refreshed_room) = - app_state.db.refresh_room(room_id, server_id).await + if let Some(mut refreshed_room) = app_state + .db + .refresh_room(room_id, server_id) + .await + .trace_err() { tracing::info!( room_id = room_id.0, diff --git a/crates/collab/src/tests/integration_tests.rs b/crates/collab/src/tests/integration_tests.rs index f70fdfb0ba..521c7515bd 100644 --- a/crates/collab/src/tests/integration_tests.rs +++ b/crates/collab/src/tests/integration_tests.rs @@ -733,6 +733,14 @@ async fn test_server_restarts( deterministic.forbid_parking(); let mut server = TestServer::start(&deterministic).await; let client_a = server.create_client(cx_a, "user_a").await; + client_a + .fs + .insert_tree("/a", json!({ "a.txt": "a-contents" })) + .await; + + // Invite client B to collaborate on a project + let (project_a, _) = client_a.build_local_project("/a", cx_a).await; + let client_b = server.create_client(cx_b, "user_b").await; let client_c = server.create_client(cx_c, "user_c").await; let client_d = server.create_client(cx_d, "user_d").await; @@ -753,19 +761,19 @@ async fn test_server_restarts( // User A calls users B, C, and D. active_call_a .update(cx_a, |call, cx| { - call.invite(client_b.user_id().unwrap(), None, cx) + call.invite(client_b.user_id().unwrap(), Some(project_a.clone()), cx) }) .await .unwrap(); active_call_a .update(cx_a, |call, cx| { - call.invite(client_c.user_id().unwrap(), None, cx) + call.invite(client_c.user_id().unwrap(), Some(project_a.clone()), cx) }) .await .unwrap(); active_call_a .update(cx_a, |call, cx| { - call.invite(client_d.user_id().unwrap(), None, cx) + call.invite(client_d.user_id().unwrap(), Some(project_a.clone()), cx) }) .await .unwrap();