Add an RPC handler for channel buffer acks
co-authored-by: max <max@zed.dev>
This commit is contained in:
parent
dd0edcd203
commit
4d61d01943
6 changed files with 54 additions and 14 deletions
|
@ -2,7 +2,7 @@ mod channel_buffer;
|
||||||
mod channel_chat;
|
mod channel_chat;
|
||||||
mod channel_store;
|
mod channel_store;
|
||||||
|
|
||||||
pub use channel_buffer::{ChannelBuffer, ChannelBufferEvent};
|
pub use channel_buffer::{ChannelBuffer, ChannelBufferEvent, ACKNOWLEDGE_DEBOUNCE_INTERVAL};
|
||||||
pub use channel_chat::{ChannelChat, ChannelChatEvent, ChannelMessage, ChannelMessageId};
|
pub use channel_chat::{ChannelChat, ChannelChatEvent, ChannelMessage, ChannelMessageId};
|
||||||
pub use channel_store::{
|
pub use channel_store::{
|
||||||
Channel, ChannelData, ChannelEvent, ChannelId, ChannelMembership, ChannelPath, ChannelStore,
|
Channel, ChannelData, ChannelEvent, ChannelId, ChannelMembership, ChannelPath, ChannelStore,
|
||||||
|
|
|
@ -11,7 +11,7 @@ use rpc::{
|
||||||
use std::{sync::Arc, time::Duration};
|
use std::{sync::Arc, time::Duration};
|
||||||
use util::ResultExt;
|
use util::ResultExt;
|
||||||
|
|
||||||
const ACKNOWLEDGE_DEBOUNCE_INTERVAL: Duration = Duration::from_millis(250);
|
pub const ACKNOWLEDGE_DEBOUNCE_INTERVAL: Duration = Duration::from_millis(250);
|
||||||
|
|
||||||
pub(crate) fn init(client: &Arc<Client>) {
|
pub(crate) fn init(client: &Arc<Client>) {
|
||||||
client.add_model_message_handler(ChannelBuffer::handle_update_channel_buffer);
|
client.add_model_message_handler(ChannelBuffer::handle_update_channel_buffer);
|
||||||
|
|
|
@ -3,8 +3,8 @@ mod connection_pool;
|
||||||
use crate::{
|
use crate::{
|
||||||
auth,
|
auth,
|
||||||
db::{
|
db::{
|
||||||
self, ChannelId, ChannelsForUser, Database, MessageId, ProjectId, RoomId, ServerId, User,
|
self, BufferId, ChannelId, ChannelsForUser, Database, MessageId, ProjectId, RoomId,
|
||||||
UserId,
|
ServerId, User, UserId,
|
||||||
},
|
},
|
||||||
executor::Executor,
|
executor::Executor,
|
||||||
AppState, Result,
|
AppState, Result,
|
||||||
|
@ -275,7 +275,8 @@ impl Server {
|
||||||
.add_message_handler(update_followers)
|
.add_message_handler(update_followers)
|
||||||
.add_message_handler(update_diff_base)
|
.add_message_handler(update_diff_base)
|
||||||
.add_request_handler(get_private_user_info)
|
.add_request_handler(get_private_user_info)
|
||||||
.add_message_handler(acknowledge_channel_message);
|
.add_message_handler(acknowledge_channel_message)
|
||||||
|
.add_message_handler(acknowledge_buffer_version);
|
||||||
|
|
||||||
Arc::new(server)
|
Arc::new(server)
|
||||||
}
|
}
|
||||||
|
@ -2912,6 +2913,24 @@ async fn acknowledge_channel_message(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn acknowledge_buffer_version(
|
||||||
|
request: proto::AckBufferOperation,
|
||||||
|
session: Session,
|
||||||
|
) -> Result<()> {
|
||||||
|
let buffer_id = BufferId::from_proto(request.buffer_id);
|
||||||
|
session
|
||||||
|
.db()
|
||||||
|
.await
|
||||||
|
.observe_buffer_version(
|
||||||
|
buffer_id,
|
||||||
|
session.user_id,
|
||||||
|
request.epoch as i32,
|
||||||
|
&request.version,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
async fn join_channel_chat(
|
async fn join_channel_chat(
|
||||||
request: proto::JoinChannelChat,
|
request: proto::JoinChannelChat,
|
||||||
response: Response<proto::JoinChannelChat>,
|
response: Response<proto::JoinChannelChat>,
|
||||||
|
|
|
@ -3,7 +3,7 @@ use crate::{
|
||||||
tests::TestServer,
|
tests::TestServer,
|
||||||
};
|
};
|
||||||
use call::ActiveCall;
|
use call::ActiveCall;
|
||||||
use channel::Channel;
|
use channel::{Channel, ACKNOWLEDGE_DEBOUNCE_INTERVAL};
|
||||||
use client::ParticipantIndex;
|
use client::ParticipantIndex;
|
||||||
use client::{Collaborator, UserId};
|
use client::{Collaborator, UserId};
|
||||||
use collab_ui::channel_view::ChannelView;
|
use collab_ui::channel_view::ChannelView;
|
||||||
|
@ -800,7 +800,6 @@ async fn test_channel_buffer_changes(
|
||||||
.has_channel_buffer_changed(channel_id)
|
.has_channel_buffer_changed(channel_id)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
});
|
});
|
||||||
|
|
||||||
assert!(has_buffer_changed);
|
assert!(has_buffer_changed);
|
||||||
|
|
||||||
// Opening the buffer should clear the changed flag.
|
// Opening the buffer should clear the changed flag.
|
||||||
|
@ -810,7 +809,6 @@ async fn test_channel_buffer_changes(
|
||||||
.update(|cx| ChannelView::open(channel_id, workspace_b.clone(), cx))
|
.update(|cx| ChannelView::open(channel_id, workspace_b.clone(), cx))
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
deterministic.run_until_parked();
|
deterministic.run_until_parked();
|
||||||
|
|
||||||
let has_buffer_changed = cx_b.read(|cx| {
|
let has_buffer_changed = cx_b.read(|cx| {
|
||||||
|
@ -820,10 +818,9 @@ async fn test_channel_buffer_changes(
|
||||||
.has_channel_buffer_changed(channel_id)
|
.has_channel_buffer_changed(channel_id)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
});
|
});
|
||||||
|
|
||||||
assert!(!has_buffer_changed);
|
assert!(!has_buffer_changed);
|
||||||
|
|
||||||
// Editing the channel while the buffer is open shuold not show that the buffer has changed.
|
// Editing the channel while the buffer is open should not show that the buffer has changed.
|
||||||
channel_buffer_a.update(cx_a, |buffer, cx| {
|
channel_buffer_a.update(cx_a, |buffer, cx| {
|
||||||
buffer.buffer().update(cx, |buffer, cx| {
|
buffer.buffer().update(cx, |buffer, cx| {
|
||||||
buffer.edit([(0..0, "2")], None, cx);
|
buffer.edit([(0..0, "2")], None, cx);
|
||||||
|
@ -838,7 +835,20 @@ async fn test_channel_buffer_changes(
|
||||||
.has_channel_buffer_changed(channel_id)
|
.has_channel_buffer_changed(channel_id)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
});
|
});
|
||||||
|
assert!(!has_buffer_changed);
|
||||||
|
|
||||||
|
deterministic.advance_clock(ACKNOWLEDGE_DEBOUNCE_INTERVAL);
|
||||||
|
|
||||||
|
// Test that the server is tracking things correctly, and we retain our 'not changed'
|
||||||
|
// state across a disconnect
|
||||||
|
server.simulate_long_connection_interruption(client_b.peer_id().unwrap(), &deterministic);
|
||||||
|
let has_buffer_changed = cx_b.read(|cx| {
|
||||||
|
client_b
|
||||||
|
.channel_store()
|
||||||
|
.read(cx)
|
||||||
|
.has_channel_buffer_changed(channel_id)
|
||||||
|
.unwrap()
|
||||||
|
});
|
||||||
assert!(!has_buffer_changed);
|
assert!(!has_buffer_changed);
|
||||||
|
|
||||||
// Closing the buffer should re-enable change tracking
|
// Closing the buffer should re-enable change tracking
|
||||||
|
@ -866,7 +876,6 @@ async fn test_channel_buffer_changes(
|
||||||
.has_channel_buffer_changed(channel_id)
|
.has_channel_buffer_changed(channel_id)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
});
|
});
|
||||||
|
|
||||||
assert!(has_buffer_changed);
|
assert!(has_buffer_changed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
db::{tests::TestDb, NewUserParams, UserId},
|
db::{tests::TestDb, NewUserParams, UserId},
|
||||||
executor::Executor,
|
executor::Executor,
|
||||||
rpc::{Server, CLEANUP_TIMEOUT},
|
rpc::{Server, CLEANUP_TIMEOUT, RECONNECT_TIMEOUT},
|
||||||
AppState,
|
AppState,
|
||||||
};
|
};
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
|
@ -17,6 +17,7 @@ use gpui::{executor::Deterministic, ModelHandle, Task, TestAppContext, WindowHan
|
||||||
use language::LanguageRegistry;
|
use language::LanguageRegistry;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use project::{Project, WorktreeId};
|
use project::{Project, WorktreeId};
|
||||||
|
use rpc::RECEIVE_TIMEOUT;
|
||||||
use settings::SettingsStore;
|
use settings::SettingsStore;
|
||||||
use std::{
|
use std::{
|
||||||
cell::{Ref, RefCell, RefMut},
|
cell::{Ref, RefCell, RefMut},
|
||||||
|
@ -255,6 +256,19 @@ impl TestServer {
|
||||||
.store(true, SeqCst);
|
.store(true, SeqCst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn simulate_long_connection_interruption(
|
||||||
|
&self,
|
||||||
|
peer_id: PeerId,
|
||||||
|
deterministic: &Arc<Deterministic>,
|
||||||
|
) {
|
||||||
|
self.forbid_connections();
|
||||||
|
self.disconnect_client(peer_id);
|
||||||
|
deterministic.advance_clock(RECEIVE_TIMEOUT + RECONNECT_TIMEOUT);
|
||||||
|
self.allow_connections();
|
||||||
|
deterministic.advance_clock(RECEIVE_TIMEOUT + RECONNECT_TIMEOUT);
|
||||||
|
deterministic.run_until_parked();
|
||||||
|
}
|
||||||
|
|
||||||
pub fn forbid_connections(&self) {
|
pub fn forbid_connections(&self) {
|
||||||
self.forbid_connections.store(true, SeqCst);
|
self.forbid_connections.store(true, SeqCst);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2760,11 +2760,9 @@ impl CollabPanel {
|
||||||
.read(cx)
|
.read(cx)
|
||||||
.channel_id()?;
|
.channel_id()?;
|
||||||
|
|
||||||
dbg!(call_channel, channel.id);
|
|
||||||
Some(call_channel == channel.id)
|
Some(call_channel == channel.id)
|
||||||
})
|
})
|
||||||
.unwrap_or(false);
|
.unwrap_or(false);
|
||||||
dbg!(is_active);
|
|
||||||
if is_active {
|
if is_active {
|
||||||
self.open_channel_notes(
|
self.open_channel_notes(
|
||||||
&OpenChannelNotes {
|
&OpenChannelNotes {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue