From 2dbea2804c1e78ac77f8b0caa37bb48d0b5675ac Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Sat, 12 Feb 2022 13:56:07 +0100 Subject: [PATCH] Deserialize buffers synchronously when deserializing project transaction On guests, this ensures we never miss updates to subsequent buffers in the project transaction that arrive while we're waiting for edits on a prior buffer in the transaction. --- crates/project/src/project.rs | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index e678ce4f08..655936401d 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -2594,18 +2594,26 @@ impl Project { } fn deserialize_project_transaction( - &self, + &mut self, message: proto::ProjectTransaction, push_to_history: bool, cx: &mut ModelContext, ) -> Task> { - cx.spawn(|this, mut cx| async move { - let mut project_transaction = ProjectTransaction::default(); - for (buffer, transaction) in message.buffers.into_iter().zip(message.transactions) { - let buffer = - this.update(&mut cx, |this, cx| this.deserialize_buffer(buffer, cx))?; - let transaction = language::proto::deserialize_transaction(transaction)?; + let mut project_transaction = ProjectTransaction::default(); + for (buffer, transaction) in message.buffers.into_iter().zip(message.transactions) { + let buffer = match self.deserialize_buffer(buffer, cx) { + Ok(buffer) => buffer, + Err(error) => return Task::ready(Err(error)), + }; + let transaction = match language::proto::deserialize_transaction(transaction) { + Ok(transaction) => transaction, + Err(error) => return Task::ready(Err(error)), + }; + project_transaction.0.insert(buffer, transaction); + } + cx.spawn_weak(|_, mut cx| async move { + for (buffer, transaction) in &project_transaction.0 { buffer .update(&mut cx, |buffer, _| { buffer.wait_for_edits(transaction.edit_ids.iter().copied()) @@ -2617,9 +2625,8 @@ impl Project { buffer.push_transaction(transaction.clone(), Instant::now()); }); } - - project_transaction.0.insert(buffer, transaction); } + Ok(project_transaction) }) }