mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-12 13:24:19 +00:00
Maintain a set of peers as they join and leave the worktree
This commit is contained in:
parent
ab089b6575
commit
7704291432
4 changed files with 98 additions and 13 deletions
|
@ -16,7 +16,8 @@ message Envelope {
|
||||||
OpenBufferResponse open_buffer_response = 11;
|
OpenBufferResponse open_buffer_response = 11;
|
||||||
CloseBuffer close_buffer = 12;
|
CloseBuffer close_buffer = 12;
|
||||||
UpdateBuffer update_buffer = 13;
|
UpdateBuffer update_buffer = 13;
|
||||||
RemoveGuest remove_guest = 14;
|
AddGuest add_guest = 14;
|
||||||
|
RemoveGuest remove_guest = 15;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,19 +46,20 @@ message OpenWorktree {
|
||||||
|
|
||||||
message OpenWorktreeResponse {
|
message OpenWorktreeResponse {
|
||||||
Worktree worktree = 1;
|
Worktree worktree = 1;
|
||||||
optional uint32 replica_id = 2;
|
uint32 replica_id = 2;
|
||||||
|
uint32 host_peer_id = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
message AddGuest {
|
message AddGuest {
|
||||||
uint64 worktree_id = 1;
|
uint64 worktree_id = 1;
|
||||||
uint32 replica_id = 2;
|
uint32 peer_id = 2;
|
||||||
User user = 3;
|
uint32 replica_id = 3;
|
||||||
|
User user = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
message RemoveGuest {
|
message RemoveGuest {
|
||||||
uint64 worktree_id = 1;
|
uint64 worktree_id = 1;
|
||||||
uint32 peer_id = 2;
|
uint32 peer_id = 2;
|
||||||
uint32 replica_id = 3;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
message OpenBuffer {
|
message OpenBuffer {
|
||||||
|
|
|
@ -74,6 +74,7 @@ request_message!(OpenWorktree, OpenWorktreeResponse);
|
||||||
request_message!(OpenBuffer, OpenBufferResponse);
|
request_message!(OpenBuffer, OpenBufferResponse);
|
||||||
message!(CloseBuffer);
|
message!(CloseBuffer);
|
||||||
message!(UpdateBuffer);
|
message!(UpdateBuffer);
|
||||||
|
message!(AddGuest);
|
||||||
message!(RemoveGuest);
|
message!(RemoveGuest);
|
||||||
|
|
||||||
/// A stream of protobuf messages.
|
/// A stream of protobuf messages.
|
||||||
|
|
|
@ -1494,7 +1494,7 @@ impl Buffer {
|
||||||
self.operations.push(operation);
|
self.operations.push(operation);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn peer_left(&mut self, replica_id: ReplicaId, cx: &mut ModelContext<Self>) {
|
pub fn remove_guest(&mut self, replica_id: ReplicaId, cx: &mut ModelContext<Self>) {
|
||||||
self.selections
|
self.selections
|
||||||
.retain(|set_id, _| set_id.replica_id != replica_id);
|
.retain(|set_id, _| set_id.replica_id != replica_id);
|
||||||
cx.notify();
|
cx.notify();
|
||||||
|
|
|
@ -37,6 +37,7 @@ use std::{
|
||||||
fmt, fs,
|
fmt, fs,
|
||||||
future::Future,
|
future::Future,
|
||||||
io,
|
io,
|
||||||
|
iter::FromIterator,
|
||||||
ops::Deref,
|
ops::Deref,
|
||||||
os::unix::fs::MetadataExt,
|
os::unix::fs::MetadataExt,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
|
@ -53,6 +54,7 @@ lazy_static! {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init(cx: &mut MutableAppContext, rpc: rpc::Client) {
|
pub fn init(cx: &mut MutableAppContext, rpc: rpc::Client) {
|
||||||
|
rpc.on_message(remote::add_guest, cx);
|
||||||
rpc.on_message(remote::remove_guest, cx);
|
rpc.on_message(remote::remove_guest, cx);
|
||||||
rpc.on_message(remote::open_buffer, cx);
|
rpc.on_message(remote::open_buffer, cx);
|
||||||
rpc.on_message(remote::close_buffer, cx);
|
rpc.on_message(remote::close_buffer, cx);
|
||||||
|
@ -100,16 +102,16 @@ impl Worktree {
|
||||||
let worktree_message = open_worktree_response
|
let worktree_message = open_worktree_response
|
||||||
.worktree
|
.worktree
|
||||||
.ok_or_else(|| anyhow!("empty worktree"))?;
|
.ok_or_else(|| anyhow!("empty worktree"))?;
|
||||||
let replica_id = open_worktree_response
|
let replica_id = open_worktree_response.replica_id;
|
||||||
.replica_id
|
let host_peer_id = PeerId(open_worktree_response.host_peer_id);
|
||||||
.ok_or_else(|| anyhow!("empty replica id"))?;
|
|
||||||
let worktree = cx.update(|cx| {
|
let worktree = cx.update(|cx| {
|
||||||
cx.add_model(|cx| {
|
cx.add_model(|cx| {
|
||||||
Worktree::Remote(RemoteWorktree::new(
|
Worktree::Remote(RemoteWorktree::new(
|
||||||
id,
|
id,
|
||||||
|
replica_id as ReplicaId,
|
||||||
|
host_peer_id,
|
||||||
worktree_message,
|
worktree_message,
|
||||||
rpc.clone(),
|
rpc.clone(),
|
||||||
replica_id as ReplicaId,
|
|
||||||
languages,
|
languages,
|
||||||
cx,
|
cx,
|
||||||
))
|
))
|
||||||
|
@ -154,6 +156,17 @@ impl Worktree {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn add_guest(
|
||||||
|
&mut self,
|
||||||
|
envelope: TypedEnvelope<proto::AddGuest>,
|
||||||
|
cx: &mut ModelContext<Worktree>,
|
||||||
|
) -> Result<()> {
|
||||||
|
match self {
|
||||||
|
Worktree::Local(worktree) => worktree.add_guest(envelope, cx),
|
||||||
|
Worktree::Remote(worktree) => worktree.add_guest(envelope, cx),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn remove_guest(
|
pub fn remove_guest(
|
||||||
&mut self,
|
&mut self,
|
||||||
envelope: TypedEnvelope<proto::RemoveGuest>,
|
envelope: TypedEnvelope<proto::RemoveGuest>,
|
||||||
|
@ -161,7 +174,7 @@ impl Worktree {
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
match self {
|
match self {
|
||||||
Worktree::Local(worktree) => worktree.remove_guest(envelope, cx),
|
Worktree::Local(worktree) => worktree.remove_guest(envelope, cx),
|
||||||
Worktree::Remote(_) => todo!(),
|
Worktree::Remote(worktree) => worktree.remove_guest(envelope, cx),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,6 +274,7 @@ pub struct LocalWorktree {
|
||||||
rpc: Option<(rpc::Client, u64)>,
|
rpc: Option<(rpc::Client, u64)>,
|
||||||
open_buffers: HashMap<usize, WeakModelHandle<Buffer>>,
|
open_buffers: HashMap<usize, WeakModelHandle<Buffer>>,
|
||||||
shared_buffers: HashMap<PeerId, HashMap<u64, ModelHandle<Buffer>>>,
|
shared_buffers: HashMap<PeerId, HashMap<u64, ModelHandle<Buffer>>>,
|
||||||
|
peers: HashMap<PeerId, ReplicaId>,
|
||||||
languages: Arc<LanguageRegistry>,
|
languages: Arc<LanguageRegistry>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,6 +312,7 @@ impl LocalWorktree {
|
||||||
poll_scheduled: false,
|
poll_scheduled: false,
|
||||||
open_buffers: Default::default(),
|
open_buffers: Default::default(),
|
||||||
shared_buffers: Default::default(),
|
shared_buffers: Default::default(),
|
||||||
|
peers: Default::default(),
|
||||||
rpc: None,
|
rpc: None,
|
||||||
languages,
|
languages,
|
||||||
};
|
};
|
||||||
|
@ -422,12 +437,34 @@ impl LocalWorktree {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn add_guest(
|
||||||
|
&mut self,
|
||||||
|
envelope: TypedEnvelope<proto::AddGuest>,
|
||||||
|
cx: &mut ModelContext<Worktree>,
|
||||||
|
) -> Result<()> {
|
||||||
|
self.peers.insert(
|
||||||
|
PeerId(envelope.payload.peer_id),
|
||||||
|
envelope.payload.replica_id as ReplicaId,
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn remove_guest(
|
pub fn remove_guest(
|
||||||
&mut self,
|
&mut self,
|
||||||
envelope: TypedEnvelope<proto::RemoveGuest>,
|
envelope: TypedEnvelope<proto::RemoveGuest>,
|
||||||
cx: &mut ModelContext<Worktree>,
|
cx: &mut ModelContext<Worktree>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
self.shared_buffers.remove(&envelope.original_sender_id()?);
|
let peer_id = PeerId(envelope.payload.peer_id);
|
||||||
|
let replica_id = self
|
||||||
|
.peers
|
||||||
|
.remove(&peer_id)
|
||||||
|
.ok_or_else(|| anyhow!("unknown peer {:?}", peer_id))?;
|
||||||
|
self.shared_buffers.remove(&peer_id);
|
||||||
|
for (_, buffer) in &self.open_buffers {
|
||||||
|
if let Some(buffer) = buffer.upgrade(&cx) {
|
||||||
|
buffer.update(cx, |buffer, cx| buffer.remove_guest(replica_id, cx));
|
||||||
|
}
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -715,15 +752,17 @@ pub struct RemoteWorktree {
|
||||||
rpc: rpc::Client,
|
rpc: rpc::Client,
|
||||||
replica_id: ReplicaId,
|
replica_id: ReplicaId,
|
||||||
open_buffers: HashMap<usize, WeakModelHandle<Buffer>>,
|
open_buffers: HashMap<usize, WeakModelHandle<Buffer>>,
|
||||||
|
peers: HashMap<PeerId, ReplicaId>,
|
||||||
languages: Arc<LanguageRegistry>,
|
languages: Arc<LanguageRegistry>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RemoteWorktree {
|
impl RemoteWorktree {
|
||||||
fn new(
|
fn new(
|
||||||
remote_id: u64,
|
remote_id: u64,
|
||||||
|
replica_id: ReplicaId,
|
||||||
|
host_peer_id: PeerId,
|
||||||
worktree: proto::Worktree,
|
worktree: proto::Worktree,
|
||||||
rpc: rpc::Client,
|
rpc: rpc::Client,
|
||||||
replica_id: ReplicaId,
|
|
||||||
languages: Arc<LanguageRegistry>,
|
languages: Arc<LanguageRegistry>,
|
||||||
cx: &mut ModelContext<Worktree>,
|
cx: &mut ModelContext<Worktree>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
@ -779,6 +818,7 @@ impl RemoteWorktree {
|
||||||
rpc,
|
rpc,
|
||||||
replica_id,
|
replica_id,
|
||||||
open_buffers: Default::default(),
|
open_buffers: Default::default(),
|
||||||
|
peers: HashMap::from_iter(Some((host_peer_id, 0))),
|
||||||
languages,
|
languages,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -837,6 +877,36 @@ impl RemoteWorktree {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn add_guest(
|
||||||
|
&mut self,
|
||||||
|
envelope: TypedEnvelope<proto::AddGuest>,
|
||||||
|
cx: &mut ModelContext<Worktree>,
|
||||||
|
) -> Result<()> {
|
||||||
|
self.peers.insert(
|
||||||
|
PeerId(envelope.payload.peer_id),
|
||||||
|
envelope.payload.replica_id as ReplicaId,
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove_guest(
|
||||||
|
&mut self,
|
||||||
|
envelope: TypedEnvelope<proto::RemoveGuest>,
|
||||||
|
cx: &mut ModelContext<Worktree>,
|
||||||
|
) -> Result<()> {
|
||||||
|
let peer_id = PeerId(envelope.payload.peer_id);
|
||||||
|
let replica_id = self
|
||||||
|
.peers
|
||||||
|
.remove(&peer_id)
|
||||||
|
.ok_or_else(|| anyhow!("unknown peer {:?}", peer_id))?;
|
||||||
|
for (_, buffer) in &self.open_buffers {
|
||||||
|
if let Some(buffer) = buffer.upgrade(&cx) {
|
||||||
|
buffer.update(cx, |buffer, cx| buffer.remove_guest(replica_id, cx));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -1938,6 +2008,18 @@ impl<'a> Iterator for ChildEntriesIter<'a> {
|
||||||
mod remote {
|
mod remote {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
pub async fn add_guest(
|
||||||
|
envelope: TypedEnvelope<proto::AddGuest>,
|
||||||
|
rpc: &rpc::Client,
|
||||||
|
cx: &mut AsyncAppContext,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
rpc.state
|
||||||
|
.lock()
|
||||||
|
.await
|
||||||
|
.shared_worktree(envelope.payload.worktree_id, cx)?
|
||||||
|
.update(cx, |worktree, cx| worktree.add_guest(envelope, cx))
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn remove_guest(
|
pub async fn remove_guest(
|
||||||
envelope: TypedEnvelope<proto::RemoveGuest>,
|
envelope: TypedEnvelope<proto::RemoveGuest>,
|
||||||
rpc: &rpc::Client,
|
rpc: &rpc::Client,
|
||||||
|
|
Loading…
Reference in a new issue