Distinguish between "foreground" and "background" RPC messages
Some types of messages, which entail state updates on the host, should be processed in the order that they were sent. Other types of messages should not block the processing of other messages. Co-Authored-By: Antonio Scandurra <me@as-cii.com>
This commit is contained in:
parent
20858699bc
commit
cf4291a126
2 changed files with 76 additions and 58 deletions
|
@ -13,6 +13,7 @@ include!(concat!(env!("OUT_DIR"), "/zed.messages.rs"));
|
||||||
|
|
||||||
pub trait EnvelopedMessage: Clone + Sized + Send + Sync + 'static {
|
pub trait EnvelopedMessage: Clone + Sized + Send + Sync + 'static {
|
||||||
const NAME: &'static str;
|
const NAME: &'static str;
|
||||||
|
const PRIORITY: MessagePriority;
|
||||||
fn into_envelope(
|
fn into_envelope(
|
||||||
self,
|
self,
|
||||||
id: u32,
|
id: u32,
|
||||||
|
@ -35,6 +36,12 @@ pub trait AnyTypedEnvelope: 'static + Send + Sync {
|
||||||
fn payload_type_name(&self) -> &'static str;
|
fn payload_type_name(&self) -> &'static str;
|
||||||
fn as_any(&self) -> &dyn Any;
|
fn as_any(&self) -> &dyn Any;
|
||||||
fn into_any(self: Box<Self>) -> Box<dyn Any + Send + Sync>;
|
fn into_any(self: Box<Self>) -> Box<dyn Any + Send + Sync>;
|
||||||
|
fn is_background(&self) -> bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum MessagePriority {
|
||||||
|
Foreground,
|
||||||
|
Background,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: EnvelopedMessage> AnyTypedEnvelope for TypedEnvelope<T> {
|
impl<T: EnvelopedMessage> AnyTypedEnvelope for TypedEnvelope<T> {
|
||||||
|
@ -53,10 +60,14 @@ impl<T: EnvelopedMessage> AnyTypedEnvelope for TypedEnvelope<T> {
|
||||||
fn into_any(self: Box<Self>) -> Box<dyn Any + Send + Sync> {
|
fn into_any(self: Box<Self>) -> Box<dyn Any + Send + Sync> {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_background(&self) -> bool {
|
||||||
|
matches!(T::PRIORITY, MessagePriority::Background)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! messages {
|
macro_rules! messages {
|
||||||
($($name:ident),* $(,)?) => {
|
($(($name:ident, $priority:ident)),* $(,)?) => {
|
||||||
pub fn build_typed_envelope(sender_id: ConnectionId, envelope: Envelope) -> Option<Box<dyn AnyTypedEnvelope>> {
|
pub fn build_typed_envelope(sender_id: ConnectionId, envelope: Envelope) -> Option<Box<dyn AnyTypedEnvelope>> {
|
||||||
match envelope.payload {
|
match envelope.payload {
|
||||||
$(Some(envelope::Payload::$name(payload)) => {
|
$(Some(envelope::Payload::$name(payload)) => {
|
||||||
|
@ -74,6 +85,7 @@ macro_rules! messages {
|
||||||
$(
|
$(
|
||||||
impl EnvelopedMessage for $name {
|
impl EnvelopedMessage for $name {
|
||||||
const NAME: &'static str = std::stringify!($name);
|
const NAME: &'static str = std::stringify!($name);
|
||||||
|
const PRIORITY: MessagePriority = MessagePriority::$priority;
|
||||||
|
|
||||||
fn into_envelope(
|
fn into_envelope(
|
||||||
self,
|
self,
|
||||||
|
@ -120,60 +132,60 @@ macro_rules! entity_messages {
|
||||||
}
|
}
|
||||||
|
|
||||||
messages!(
|
messages!(
|
||||||
Ack,
|
(Ack, Foreground),
|
||||||
AddProjectCollaborator,
|
(AddProjectCollaborator, Foreground),
|
||||||
ApplyCodeAction,
|
(ApplyCodeAction, Foreground),
|
||||||
ApplyCodeActionResponse,
|
(ApplyCodeActionResponse, Foreground),
|
||||||
ApplyCompletionAdditionalEdits,
|
(ApplyCompletionAdditionalEdits, Foreground),
|
||||||
ApplyCompletionAdditionalEditsResponse,
|
(ApplyCompletionAdditionalEditsResponse, Foreground),
|
||||||
BufferReloaded,
|
(BufferReloaded, Foreground),
|
||||||
BufferSaved,
|
(BufferSaved, Foreground),
|
||||||
ChannelMessageSent,
|
(ChannelMessageSent, Foreground),
|
||||||
CloseBuffer,
|
(CloseBuffer, Foreground),
|
||||||
DiskBasedDiagnosticsUpdated,
|
(DiskBasedDiagnosticsUpdated, Background),
|
||||||
DiskBasedDiagnosticsUpdating,
|
(DiskBasedDiagnosticsUpdating, Background),
|
||||||
Error,
|
(Error, Foreground),
|
||||||
FormatBuffers,
|
(FormatBuffers, Foreground),
|
||||||
FormatBuffersResponse,
|
(FormatBuffersResponse, Foreground),
|
||||||
GetChannelMessages,
|
(GetChannelMessages, Foreground),
|
||||||
GetChannelMessagesResponse,
|
(GetChannelMessagesResponse, Foreground),
|
||||||
GetChannels,
|
(GetChannels, Foreground),
|
||||||
GetChannelsResponse,
|
(GetChannelsResponse, Foreground),
|
||||||
GetCodeActions,
|
(GetCodeActions, Background),
|
||||||
GetCodeActionsResponse,
|
(GetCodeActionsResponse, Foreground),
|
||||||
GetCompletions,
|
(GetCompletions, Background),
|
||||||
GetCompletionsResponse,
|
(GetCompletionsResponse, Foreground),
|
||||||
GetDefinition,
|
(GetDefinition, Foreground),
|
||||||
GetDefinitionResponse,
|
(GetDefinitionResponse, Foreground),
|
||||||
GetUsers,
|
(GetUsers, Foreground),
|
||||||
GetUsersResponse,
|
(GetUsersResponse, Foreground),
|
||||||
JoinChannel,
|
(JoinChannel, Foreground),
|
||||||
JoinChannelResponse,
|
(JoinChannelResponse, Foreground),
|
||||||
JoinProject,
|
(JoinProject, Foreground),
|
||||||
JoinProjectResponse,
|
(JoinProjectResponse, Foreground),
|
||||||
LeaveChannel,
|
(LeaveChannel, Foreground),
|
||||||
LeaveProject,
|
(LeaveProject, Foreground),
|
||||||
OpenBuffer,
|
(OpenBuffer, Foreground),
|
||||||
OpenBufferResponse,
|
(OpenBufferResponse, Foreground),
|
||||||
RegisterProjectResponse,
|
(RegisterProjectResponse, Foreground),
|
||||||
Ping,
|
(Ping, Foreground),
|
||||||
RegisterProject,
|
(RegisterProject, Foreground),
|
||||||
RegisterWorktree,
|
(RegisterWorktree, Foreground),
|
||||||
RemoveProjectCollaborator,
|
(RemoveProjectCollaborator, Foreground),
|
||||||
SaveBuffer,
|
(SaveBuffer, Foreground),
|
||||||
SendChannelMessage,
|
(SendChannelMessage, Foreground),
|
||||||
SendChannelMessageResponse,
|
(SendChannelMessageResponse, Foreground),
|
||||||
ShareProject,
|
(ShareProject, Foreground),
|
||||||
ShareWorktree,
|
(ShareWorktree, Foreground),
|
||||||
Test,
|
(Test, Foreground),
|
||||||
UnregisterProject,
|
(UnregisterProject, Foreground),
|
||||||
UnregisterWorktree,
|
(UnregisterWorktree, Foreground),
|
||||||
UnshareProject,
|
(UnshareProject, Foreground),
|
||||||
UpdateBuffer,
|
(UpdateBuffer, Foreground),
|
||||||
UpdateBufferFile,
|
(UpdateBufferFile, Foreground),
|
||||||
UpdateContacts,
|
(UpdateContacts, Foreground),
|
||||||
UpdateDiagnosticSummary,
|
(UpdateDiagnosticSummary, Foreground),
|
||||||
UpdateWorktree,
|
(UpdateWorktree, Foreground),
|
||||||
);
|
);
|
||||||
|
|
||||||
request_messages!(
|
request_messages!(
|
||||||
|
|
|
@ -190,9 +190,10 @@ impl Server {
|
||||||
let type_name = message.payload_type_name();
|
let type_name = message.payload_type_name();
|
||||||
log::info!("rpc message received. connection:{}, type:{}", connection_id, type_name);
|
log::info!("rpc message received. connection:{}, type:{}", connection_id, type_name);
|
||||||
if let Some(handler) = this.handlers.get(&message.payload_type_id()) {
|
if let Some(handler) = this.handlers.get(&message.payload_type_id()) {
|
||||||
let handle_message = (handler)(this.clone(), message);
|
|
||||||
let notifications = this.notifications.clone();
|
let notifications = this.notifications.clone();
|
||||||
executor.spawn_detached(async move {
|
let is_background = message.is_background();
|
||||||
|
let handle_message = (handler)(this.clone(), message);
|
||||||
|
let handle_message = async move {
|
||||||
if let Err(err) = handle_message.await {
|
if let Err(err) = handle_message.await {
|
||||||
log::error!("rpc message error. connection:{}, type:{}, error:{:?}", connection_id, type_name, err);
|
log::error!("rpc message error. connection:{}, type:{}, error:{:?}", connection_id, type_name, err);
|
||||||
} else {
|
} else {
|
||||||
|
@ -201,7 +202,12 @@ impl Server {
|
||||||
if let Some(mut notifications) = notifications {
|
if let Some(mut notifications) = notifications {
|
||||||
let _ = notifications.send(()).await;
|
let _ = notifications.send(()).await;
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
if is_background {
|
||||||
|
executor.spawn_detached(handle_message);
|
||||||
|
} else {
|
||||||
|
handle_message.await;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
log::warn!("unhandled message: {}", type_name);
|
log::warn!("unhandled message: {}", type_name);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue