diff --git a/crates/collab/src/db.rs b/crates/collab/src/db.rs index b2cb5ac90b..94ccaffb97 100644 --- a/crates/collab/src/db.rs +++ b/crates/collab/src/db.rs @@ -415,7 +415,7 @@ impl Database { if is_serialization_error(error) && prev_attempt_count < SLEEPS.len() { let base_delay = SLEEPS[prev_attempt_count]; let randomized_delay = base_delay * self.rng.lock().await.gen_range(0.5..=2.0); - log::info!( + log::warn!( "retrying transaction after serialization error. delay: {} ms.", randomized_delay ); diff --git a/crates/collab/src/db/queries/projects.rs b/crates/collab/src/db/queries/projects.rs index b9e917bbbc..2a7c3e1f8c 100644 --- a/crates/collab/src/db/queries/projects.rs +++ b/crates/collab/src/db/queries/projects.rs @@ -130,13 +130,21 @@ impl Database { .await } + pub async fn delete_project(&self, project_id: ProjectId) -> Result<()> { + self.weak_transaction(|tx| async move { + project::Entity::delete_by_id(project_id).exec(&*tx).await?; + Ok(()) + }) + .await + } + /// Unshares the given project. pub async fn unshare_project( &self, project_id: ProjectId, connection: ConnectionId, user_id: Option, - ) -> Result, Vec)>> { + ) -> Result, Vec)>> { self.project_transaction(project_id, |tx| async move { let guest_connection_ids = self.project_guest_connection_ids(project_id, &tx).await?; let project = project::Entity::find_by_id(project_id) @@ -149,10 +157,7 @@ impl Database { None }; if project.host_connection()? == connection { - project::Entity::delete(project.into_active_model()) - .exec(&*tx) - .await?; - return Ok((room, guest_connection_ids)); + return Ok((true, room, guest_connection_ids)); } if let Some(dev_server_project_id) = project.dev_server_project_id { if let Some(user_id) = user_id { @@ -169,7 +174,7 @@ impl Database { }) .exec(&*tx) .await?; - return Ok((room, guest_connection_ids)); + return Ok((false, room, guest_connection_ids)); } } diff --git a/crates/collab/src/rpc.rs b/crates/collab/src/rpc.rs index bad78b845a..c7b8f32bde 100644 --- a/crates/collab/src/rpc.rs +++ b/crates/collab/src/rpc.rs @@ -2032,23 +2032,34 @@ async fn unshare_project_internal( user_id: Option, session: &Session, ) -> Result<()> { - let (room, guest_connection_ids) = &*session - .db() - .await - .unshare_project(project_id, connection_id, user_id) - .await?; + let delete = { + let room_guard = session + .db() + .await + .unshare_project(project_id, connection_id, user_id) + .await?; - let message = proto::UnshareProject { - project_id: project_id.to_proto(), + let (delete, room, guest_connection_ids) = &*room_guard; + + let message = proto::UnshareProject { + project_id: project_id.to_proto(), + }; + + broadcast( + Some(connection_id), + guest_connection_ids.iter().copied(), + |conn_id| session.peer.send(conn_id, message.clone()), + ); + if let Some(room) = room { + room_updated(room, &session.peer); + } + + *delete }; - broadcast( - Some(connection_id), - guest_connection_ids.iter().copied(), - |conn_id| session.peer.send(conn_id, message.clone()), - ); - if let Some(room) = room { - room_updated(room, &session.peer); + if delete { + let db = session.db().await; + db.delete_project(project_id).await?; } Ok(())