Fix bug where guest would drop BufferSaved messages while opening the buffer

This commit is contained in:
Max Brunsfeld 2023-04-03 16:23:44 -07:00
parent 543301f949
commit f95732e981
3 changed files with 35 additions and 31 deletions

View file

@ -132,7 +132,7 @@ async fn test_random_collaboration(
) )
.await; .await;
if !applied { if !applied {
skipped.store(false, SeqCst); skipped.store(true, SeqCst);
} }
} }

View file

@ -4,7 +4,7 @@ use crate::{
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use async_trait::async_trait; use async_trait::async_trait;
use client::proto::{self, PeerId}; use client::proto::{self, PeerId};
use gpui::{AppContext, AsyncAppContext, ModelHandle}; use gpui::{AppContext, AsyncAppContext, ModelHandle, MutableAppContext};
use language::{ use language::{
point_from_lsp, point_to_lsp, point_from_lsp, point_to_lsp,
proto::{deserialize_anchor, deserialize_version, serialize_anchor, serialize_version}, proto::{deserialize_anchor, deserialize_version, serialize_anchor, serialize_version},
@ -49,7 +49,7 @@ pub(crate) trait LspCommand: 'static + Sized {
project: &mut Project, project: &mut Project,
peer_id: PeerId, peer_id: PeerId,
buffer_version: &clock::Global, buffer_version: &clock::Global,
cx: &AppContext, cx: &mut MutableAppContext,
) -> <Self::ProtoRequest as proto::RequestMessage>::Response; ) -> <Self::ProtoRequest as proto::RequestMessage>::Response;
async fn response_from_proto( async fn response_from_proto(
self, self,
@ -175,7 +175,7 @@ impl LspCommand for PrepareRename {
_: &mut Project, _: &mut Project,
_: PeerId, _: PeerId,
buffer_version: &clock::Global, buffer_version: &clock::Global,
_: &AppContext, _: &mut MutableAppContext,
) -> proto::PrepareRenameResponse { ) -> proto::PrepareRenameResponse {
proto::PrepareRenameResponse { proto::PrepareRenameResponse {
can_rename: range.is_some(), can_rename: range.is_some(),
@ -296,7 +296,7 @@ impl LspCommand for PerformRename {
project: &mut Project, project: &mut Project,
peer_id: PeerId, peer_id: PeerId,
_: &clock::Global, _: &clock::Global,
cx: &AppContext, cx: &mut MutableAppContext,
) -> proto::PerformRenameResponse { ) -> proto::PerformRenameResponse {
let transaction = project.serialize_project_transaction_for_peer(response, peer_id, cx); let transaction = project.serialize_project_transaction_for_peer(response, peer_id, cx);
proto::PerformRenameResponse { proto::PerformRenameResponse {
@ -391,7 +391,7 @@ impl LspCommand for GetDefinition {
project: &mut Project, project: &mut Project,
peer_id: PeerId, peer_id: PeerId,
_: &clock::Global, _: &clock::Global,
cx: &AppContext, cx: &mut MutableAppContext,
) -> proto::GetDefinitionResponse { ) -> proto::GetDefinitionResponse {
let links = location_links_to_proto(response, project, peer_id, cx); let links = location_links_to_proto(response, project, peer_id, cx);
proto::GetDefinitionResponse { links } proto::GetDefinitionResponse { links }
@ -477,7 +477,7 @@ impl LspCommand for GetTypeDefinition {
project: &mut Project, project: &mut Project,
peer_id: PeerId, peer_id: PeerId,
_: &clock::Global, _: &clock::Global,
cx: &AppContext, cx: &mut MutableAppContext,
) -> proto::GetTypeDefinitionResponse { ) -> proto::GetTypeDefinitionResponse {
let links = location_links_to_proto(response, project, peer_id, cx); let links = location_links_to_proto(response, project, peer_id, cx);
proto::GetTypeDefinitionResponse { links } proto::GetTypeDefinitionResponse { links }
@ -658,7 +658,7 @@ fn location_links_to_proto(
links: Vec<LocationLink>, links: Vec<LocationLink>,
project: &mut Project, project: &mut Project,
peer_id: PeerId, peer_id: PeerId,
cx: &AppContext, cx: &mut MutableAppContext,
) -> Vec<proto::LocationLink> { ) -> Vec<proto::LocationLink> {
links links
.into_iter() .into_iter()
@ -787,7 +787,7 @@ impl LspCommand for GetReferences {
project: &mut Project, project: &mut Project,
peer_id: PeerId, peer_id: PeerId,
_: &clock::Global, _: &clock::Global,
cx: &AppContext, cx: &mut MutableAppContext,
) -> proto::GetReferencesResponse { ) -> proto::GetReferencesResponse {
let locations = response let locations = response
.into_iter() .into_iter()
@ -928,7 +928,7 @@ impl LspCommand for GetDocumentHighlights {
_: &mut Project, _: &mut Project,
_: PeerId, _: PeerId,
_: &clock::Global, _: &clock::Global,
_: &AppContext, _: &mut MutableAppContext,
) -> proto::GetDocumentHighlightsResponse { ) -> proto::GetDocumentHighlightsResponse {
let highlights = response let highlights = response
.into_iter() .into_iter()
@ -1130,7 +1130,7 @@ impl LspCommand for GetHover {
_: &mut Project, _: &mut Project,
_: PeerId, _: PeerId,
_: &clock::Global, _: &clock::Global,
_: &AppContext, _: &mut MutableAppContext,
) -> proto::GetHoverResponse { ) -> proto::GetHoverResponse {
if let Some(response) = response { if let Some(response) = response {
let (start, end) = if let Some(range) = response.range { let (start, end) = if let Some(range) = response.range {

View file

@ -5858,7 +5858,7 @@ impl Project {
&mut self, &mut self,
project_transaction: ProjectTransaction, project_transaction: ProjectTransaction,
peer_id: proto::PeerId, peer_id: proto::PeerId,
cx: &AppContext, cx: &mut MutableAppContext,
) -> proto::ProjectTransaction { ) -> proto::ProjectTransaction {
let mut serialized_transaction = proto::ProjectTransaction { let mut serialized_transaction = proto::ProjectTransaction {
buffer_ids: Default::default(), buffer_ids: Default::default(),
@ -5916,27 +5916,27 @@ impl Project {
&mut self, &mut self,
buffer: &ModelHandle<Buffer>, buffer: &ModelHandle<Buffer>,
peer_id: proto::PeerId, peer_id: proto::PeerId,
cx: &AppContext, cx: &mut MutableAppContext,
) -> u64 { ) -> u64 {
let buffer_id = buffer.read(cx).remote_id(); let buffer_id = buffer.read(cx).remote_id();
if let Some(project_id) = self.remote_id() { if let Some(project_id) = self.remote_id() {
let shared_buffers = self.shared_buffers.entry(peer_id).or_default(); let shared_buffers = self.shared_buffers.entry(peer_id).or_default();
if shared_buffers.insert(buffer_id) { if shared_buffers.insert(buffer_id) {
let buffer = buffer.read(cx); let buffer = buffer.clone();
let state = buffer.to_proto(); let operations = buffer.read(cx).serialize_ops(None, cx);
let operations = buffer.serialize_ops(None, cx);
let client = self.client.clone(); let client = self.client.clone();
cx.background() cx.spawn(move |cx| async move {
.spawn( let operations = operations.await;
async move { let state = buffer.read_with(&cx, |buffer, _| buffer.to_proto());
let operations = operations.await;
client.send(proto::CreateBufferForPeer { client.send(proto::CreateBufferForPeer {
project_id, project_id,
peer_id: Some(peer_id), peer_id: Some(peer_id),
variant: Some(proto::create_buffer_for_peer::Variant::State(state)), variant: Some(proto::create_buffer_for_peer::Variant::State(state)),
})?; })?;
cx.background()
.spawn(async move {
let mut chunks = split_operations(operations).peekable(); let mut chunks = split_operations(operations).peekable();
while let Some(chunk) = chunks.next() { while let Some(chunk) = chunks.next() {
let is_last = chunks.peek().is_none(); let is_last = chunks.peek().is_none();
@ -5952,12 +5952,11 @@ impl Project {
)), )),
})?; })?;
} }
anyhow::Ok(()) anyhow::Ok(())
} })
.log_err(), .await
) })
.detach(); .detach()
} }
} }
@ -6231,7 +6230,12 @@ impl Project {
let buffer = this let buffer = this
.opened_buffers .opened_buffers
.get(&envelope.payload.buffer_id) .get(&envelope.payload.buffer_id)
.and_then(|buffer| buffer.upgrade(cx)); .and_then(|buffer| buffer.upgrade(cx))
.or_else(|| {
this.incomplete_remote_buffers
.get(&envelope.payload.buffer_id)
.and_then(|b| b.clone())
});
if let Some(buffer) = buffer { if let Some(buffer) = buffer {
buffer.update(cx, |buffer, cx| { buffer.update(cx, |buffer, cx| {
buffer.did_save(version, fingerprint, mtime, cx); buffer.did_save(version, fingerprint, mtime, cx);