Send a `CloseWorktree` message when a shared `Worktree` is dropped

Antonio Scandurra created

Change summary

zed-rpc/proto/zed.proto | 17 +++++++++++------
zed-rpc/src/proto.rs    |  1 +
zed/src/worktree.rs     | 17 +++++++++++++++++
3 files changed, 29 insertions(+), 6 deletions(-)

Detailed changes

zed-rpc/proto/zed.proto 🔗

@@ -12,12 +12,13 @@ message Envelope {
         ShareWorktreeResponse share_worktree_response = 7;
         OpenWorktree open_worktree = 8;
         OpenWorktreeResponse open_worktree_response = 9;
-        OpenBuffer open_buffer = 10;
-        OpenBufferResponse open_buffer_response = 11;
-        CloseBuffer close_buffer = 12;
-        UpdateBuffer update_buffer = 13;
-        AddGuest add_guest = 14;
-        RemoveGuest remove_guest = 15;
+        CloseWorktree close_worktree = 10;
+        OpenBuffer open_buffer = 11;
+        OpenBufferResponse open_buffer_response = 12;
+        CloseBuffer close_buffer = 13;
+        UpdateBuffer update_buffer = 14;
+        AddGuest add_guest = 15;
+        RemoveGuest remove_guest = 16;
     }
 }
 
@@ -50,6 +51,10 @@ message OpenWorktreeResponse {
     repeated Peer peers = 3;
 }
 
+message CloseWorktree {
+    uint64 worktree_id = 1;
+}
+
 message AddGuest {
     uint64 worktree_id = 1;
     Peer guest = 2;

zed-rpc/src/proto.rs 🔗

@@ -71,6 +71,7 @@ macro_rules! request_message {
 request_message!(Auth, AuthResponse);
 request_message!(ShareWorktree, ShareWorktreeResponse);
 request_message!(OpenWorktree, OpenWorktreeResponse);
+message!(CloseWorktree);
 request_message!(OpenBuffer, OpenBufferResponse);
 message!(CloseBuffer);
 message!(UpdateBuffer);

zed/src/worktree.rs 🔗

@@ -74,6 +74,23 @@ pub enum Worktree {
 
 impl Entity for Worktree {
     type Event = ();
+
+    fn release(&mut self, cx: &mut MutableAppContext) {
+        let rpc = match self {
+            Self::Local(tree) => tree.rpc.clone(),
+            Self::Remote(tree) => Some((tree.rpc.clone(), tree.remote_id)),
+        };
+
+        if let Some((rpc, worktree_id)) = rpc {
+            cx.spawn(|_| async move {
+                rpc.state.lock().await.shared_worktrees.remove(&worktree_id);
+                if let Err(err) = rpc.send(proto::CloseWorktree { worktree_id }).await {
+                    log::error!("error closing worktree {}: {}", worktree_id, err);
+                }
+            })
+            .detach();
+        }
+    }
 }
 
 impl Worktree {