Make Project::share and Project::unshare private

This is still in-progress because randomized tests are failing.

Co-Authored-By: Nathan Sobo <nathan@zed.dev>
This commit is contained in:
Antonio Scandurra 2022-05-13 17:17:20 +02:00
parent be51a58311
commit dd684d26a1
2 changed files with 277 additions and 510 deletions

File diff suppressed because it is too large Load diff

View file

@ -817,11 +817,12 @@ impl Project {
} }
} }
pub fn can_share(&self, cx: &AppContext) -> bool { fn share(
self.is_local() && self.visible_worktrees(cx).next().is_some() &mut self,
} requester_user_id: UserId,
requester_peer_id: PeerId,
pub fn share(&mut self, cx: &mut ModelContext<Self>) -> Task<Result<()>> { cx: &mut ModelContext<Self>,
) -> Task<Result<()>> {
let project_id; let project_id;
if let ProjectClientState::Local { if let ProjectClientState::Local {
remote_id_rx, remote_id_rx,
@ -882,7 +883,7 @@ impl Project {
}) })
} }
pub fn unshare(&mut self, cx: &mut ModelContext<Self>) { fn unshare(&mut self, cx: &mut ModelContext<Self>) {
if let ProjectClientState::Local { is_shared, .. } = &mut self.client_state { if let ProjectClientState::Local { is_shared, .. } = &mut self.client_state {
if !*is_shared { if !*is_shared {
return; return;
@ -929,7 +930,10 @@ impl Project {
let client = self.client.clone(); let client = self.client.clone();
cx.foreground() cx.foreground()
.spawn(async move { .spawn(async move {
println!("SHARING because {} wanted to join!!!", requester_id);
share.await?; share.await?;
println!("DONE SHARING!!!!!");
client.send(proto::RespondToJoinProjectRequest { client.send(proto::RespondToJoinProjectRequest {
requester_id, requester_id,
project_id, project_id,
@ -3521,25 +3525,36 @@ impl Project {
}); });
let worktree = worktree?; let worktree = worktree?;
let (remote_project_id, is_shared) = let remote_project_id = project.update(&mut cx, |project, cx| {
project.update(&mut cx, |project, cx| {
project.add_worktree(&worktree, cx); project.add_worktree(&worktree, cx);
(project.remote_id(), project.is_shared()) project.remote_id()
}); });
if let Some(project_id) = remote_project_id { if let Some(project_id) = remote_project_id {
if is_shared { // Because sharing is async, we may have *unshared* the project by the time it completes,
worktree // in which case we need to register the worktree instead.
loop {
if project.read_with(&cx, |project, _| project.is_shared()) {
if worktree
.update(&mut cx, |worktree, cx| { .update(&mut cx, |worktree, cx| {
worktree.as_local_mut().unwrap().share(project_id, cx) worktree.as_local_mut().unwrap().share(project_id, cx)
}) })
.await?; .await
.is_ok()
{
break;
}
} else { } else {
worktree worktree
.update(&mut cx, |worktree, cx| { .update(&mut cx, |worktree, cx| {
worktree.as_local_mut().unwrap().register(project_id, cx) worktree
.as_local_mut()
.unwrap()
.register(project_id, cx)
}) })
.await?; .await?;
break;
}
} }
} }
@ -3828,7 +3843,17 @@ impl Project {
buffer.update(cx, |buffer, cx| buffer.remove_peer(replica_id, cx)); buffer.update(cx, |buffer, cx| buffer.remove_peer(replica_id, cx));
} }
} }
println!(
"{} observed {:?} leaving",
this.user_store
.read(cx)
.current_user()
.unwrap()
.github_login,
peer_id
);
if this.collaborators.is_empty() { if this.collaborators.is_empty() {
println!("UNSHARING!!!!");
this.unshare(cx); this.unshare(cx);
} }
cx.emit(Event::CollaboratorLeft(peer_id)); cx.emit(Event::CollaboratorLeft(peer_id));
@ -4087,6 +4112,7 @@ impl Project {
.into_iter() .into_iter()
.map(|op| language::proto::deserialize_operation(op)) .map(|op| language::proto::deserialize_operation(op))
.collect::<Result<Vec<_>, _>>()?; .collect::<Result<Vec<_>, _>>()?;
let is_remote = this.is_remote();
match this.opened_buffers.entry(buffer_id) { match this.opened_buffers.entry(buffer_id) {
hash_map::Entry::Occupied(mut e) => match e.get_mut() { hash_map::Entry::Occupied(mut e) => match e.get_mut() {
OpenBuffer::Strong(buffer) => { OpenBuffer::Strong(buffer) => {
@ -4096,6 +4122,11 @@ impl Project {
OpenBuffer::Weak(_) => {} OpenBuffer::Weak(_) => {}
}, },
hash_map::Entry::Vacant(e) => { hash_map::Entry::Vacant(e) => {
assert!(
is_remote,
"received buffer update from {:?}",
envelope.original_sender_id
);
e.insert(OpenBuffer::Loading(ops)); e.insert(OpenBuffer::Loading(ops));
} }
} }