Add remote worktree to project before it is fully deserialized

This prevents a race condition where the host will send us messages and
responses about a worktree that we have seen but haven't yet finished loading.
This commit is contained in:
Antonio Scandurra 2022-01-24 14:00:38 +01:00
parent 245490f934
commit a762f575f4
2 changed files with 82 additions and 80 deletions

View file

@ -247,8 +247,10 @@ impl Project {
let mut worktrees = Vec::new();
for worktree in response.worktrees {
worktrees
.push(Worktree::remote(remote_id, replica_id, worktree, client.clone(), cx).await?);
let (worktree, load_task) = cx
.update(|cx| Worktree::remote(remote_id, replica_id, worktree, client.clone(), cx));
worktrees.push(worktree);
load_task.detach();
}
let user_ids = response
@ -1464,16 +1466,9 @@ impl Project {
.payload
.worktree
.ok_or_else(|| anyhow!("invalid worktree"))?;
cx.spawn(|this, mut cx| {
async move {
let worktree =
Worktree::remote(remote_id, replica_id, worktree, client, &mut cx).await?;
this.update(&mut cx, |this, cx| this.add_worktree(&worktree, cx));
Ok(())
}
.log_err()
})
.detach();
let (worktree, load_task) = Worktree::remote(remote_id, replica_id, worktree, client, cx);
self.add_worktree(&worktree, cx);
load_task.detach();
Ok(())
}
@ -2551,15 +2546,16 @@ mod tests {
// Create a remote copy of this worktree.
let initial_snapshot = tree.read_with(&cx, |tree, _| tree.snapshot());
let remote = Worktree::remote(
1,
1,
initial_snapshot.to_proto(&Default::default(), Default::default()),
rpc.clone(),
&mut cx.to_async(),
)
.await
.unwrap();
let (remote, load_task) = cx.update(|cx| {
Worktree::remote(
1,
1,
initial_snapshot.to_proto(&Default::default(), Default::default()),
rpc.clone(),
cx,
)
});
load_task.await;
cx.read(|cx| {
assert!(!buffer2.read(cx).is_dirty());