Subscribe to worktree messages at the entity level
Co-Authored-By: Max Brunsfeld <maxbrunsfeld@gmail.com>
This commit is contained in:
co-authored by
Max Brunsfeld
parent
ef421d735d
commit
37f24d10ec
+4
-5
@@ -171,11 +171,10 @@ impl Peer {
|
||||
}
|
||||
} else {
|
||||
router.handle(connection_id, envelope.clone()).await;
|
||||
match proto::build_typed_envelope(connection_id, envelope) {
|
||||
Ok(envelope) => {
|
||||
broadcast_incoming_messages.send(envelope).await.ok();
|
||||
}
|
||||
Err(error) => log::error!("{}", error),
|
||||
if let Some(envelope) = proto::build_typed_envelope(connection_id, envelope) {
|
||||
broadcast_incoming_messages.send(envelope).await.ok();
|
||||
} else {
|
||||
log::error!("unable to construct a typed envelope");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+87
-81
@@ -1,5 +1,5 @@
|
||||
use super::{ConnectionId, PeerId, TypedEnvelope};
|
||||
use anyhow::{anyhow, Result};
|
||||
use anyhow::Result;
|
||||
use async_tungstenite::tungstenite::{Error as WebSocketError, Message as WebSocketMessage};
|
||||
use futures::{SinkExt as _, StreamExt as _};
|
||||
use prost::Message;
|
||||
@@ -24,127 +24,133 @@ pub trait EnvelopedMessage: Clone + Sized + Send + Sync + 'static {
|
||||
fn from_envelope(envelope: Envelope) -> Option<Self>;
|
||||
}
|
||||
|
||||
pub trait EntityMessage: EnvelopedMessage {
|
||||
fn remote_entity_id(&self) -> u64;
|
||||
}
|
||||
|
||||
pub trait RequestMessage: EnvelopedMessage {
|
||||
type Response: EnvelopedMessage;
|
||||
}
|
||||
|
||||
macro_rules! messages {
|
||||
($($name:ident),*) => {
|
||||
fn unicast_message_into_typed_envelope(sender_id: ConnectionId, envelope: &mut Envelope) -> Option<Arc<dyn Any + Send + Sync>> {
|
||||
match &mut envelope.payload {
|
||||
$(payload @ Some(envelope::Payload::$name(_)) => Some(Arc::new(TypedEnvelope {
|
||||
($($name:ident),* $(,)?) => {
|
||||
pub fn build_typed_envelope(sender_id: ConnectionId, envelope: Envelope) -> Option<Arc<dyn Any + Send + Sync>> {
|
||||
match envelope.payload {
|
||||
$(Some(envelope::Payload::$name(payload)) => Some(Arc::new(TypedEnvelope {
|
||||
sender_id,
|
||||
original_sender_id: envelope.original_sender_id.map(PeerId),
|
||||
message_id: envelope.id,
|
||||
payload: payload.take().unwrap(),
|
||||
payload,
|
||||
})), )*
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
||||
$(
|
||||
message!($name);
|
||||
impl EnvelopedMessage for $name {
|
||||
const NAME: &'static str = std::stringify!($name);
|
||||
|
||||
fn into_envelope(
|
||||
self,
|
||||
id: u32,
|
||||
responding_to: Option<u32>,
|
||||
original_sender_id: Option<u32>,
|
||||
) -> Envelope {
|
||||
Envelope {
|
||||
id,
|
||||
responding_to,
|
||||
original_sender_id,
|
||||
payload: Some(envelope::Payload::$name(self)),
|
||||
}
|
||||
}
|
||||
|
||||
fn matches_envelope(envelope: &Envelope) -> bool {
|
||||
matches!(&envelope.payload, Some(envelope::Payload::$name(_)))
|
||||
}
|
||||
|
||||
fn from_envelope(envelope: Envelope) -> Option<Self> {
|
||||
if let Some(envelope::Payload::$name(msg)) = envelope.payload {
|
||||
Some(msg)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! request_messages {
|
||||
($(($request_name:ident, $response_name:ident)),*) => {
|
||||
fn request_message_into_typed_envelope(sender_id: ConnectionId, envelope: Envelope) -> Option<Arc<dyn Any + Send + Sync>> {
|
||||
match envelope.payload {
|
||||
$(
|
||||
Some(envelope::Payload::$request_name(payload)) => Some(Arc::new(TypedEnvelope {
|
||||
sender_id,
|
||||
original_sender_id: envelope.original_sender_id.map(PeerId),
|
||||
message_id: envelope.id,
|
||||
payload,
|
||||
})),
|
||||
Some(envelope::Payload::$response_name(payload)) => Some(Arc::new(TypedEnvelope {
|
||||
sender_id,
|
||||
original_sender_id: envelope.original_sender_id.map(PeerId),
|
||||
message_id: envelope.id,
|
||||
payload,
|
||||
})),
|
||||
)*
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
||||
$(
|
||||
message!($request_name);
|
||||
message!($response_name);
|
||||
)*
|
||||
|
||||
($(($request_name:ident, $response_name:ident)),* $(,)?) => {
|
||||
$(impl RequestMessage for $request_name {
|
||||
type Response = $response_name;
|
||||
})*
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! message {
|
||||
($name:ident) => {
|
||||
impl EnvelopedMessage for $name {
|
||||
const NAME: &'static str = std::stringify!($name);
|
||||
|
||||
fn into_envelope(
|
||||
self,
|
||||
id: u32,
|
||||
responding_to: Option<u32>,
|
||||
original_sender_id: Option<u32>,
|
||||
) -> Envelope {
|
||||
Envelope {
|
||||
id,
|
||||
responding_to,
|
||||
original_sender_id,
|
||||
payload: Some(envelope::Payload::$name(self)),
|
||||
}
|
||||
macro_rules! entity_messages {
|
||||
($id_field:ident, $($name:ident),* $(,)?) => {
|
||||
$(impl EntityMessage for $name {
|
||||
fn remote_entity_id(&self) -> u64 {
|
||||
self.$id_field
|
||||
}
|
||||
|
||||
fn matches_envelope(envelope: &Envelope) -> bool {
|
||||
matches!(&envelope.payload, Some(envelope::Payload::$name(_)))
|
||||
}
|
||||
|
||||
fn from_envelope(envelope: Envelope) -> Option<Self> {
|
||||
if let Some(envelope::Payload::$name(msg)) = envelope.payload {
|
||||
Some(msg)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
})*
|
||||
};
|
||||
}
|
||||
|
||||
messages!(
|
||||
UpdateWorktree,
|
||||
CloseWorktree,
|
||||
CloseBuffer,
|
||||
UpdateBuffer,
|
||||
AddPeer,
|
||||
Auth,
|
||||
AuthResponse,
|
||||
BufferSaved,
|
||||
ChannelMessageSent,
|
||||
CloseBuffer,
|
||||
CloseWorktree,
|
||||
GetChannels,
|
||||
GetChannelsResponse,
|
||||
GetUsers,
|
||||
GetUsersResponse,
|
||||
JoinChannel,
|
||||
JoinChannelResponse,
|
||||
OpenBuffer,
|
||||
OpenBufferResponse,
|
||||
OpenWorktree,
|
||||
OpenWorktreeResponse,
|
||||
RemovePeer,
|
||||
SaveBuffer,
|
||||
SendChannelMessage,
|
||||
ChannelMessageSent
|
||||
ShareWorktree,
|
||||
ShareWorktreeResponse,
|
||||
UpdateBuffer,
|
||||
UpdateWorktree,
|
||||
);
|
||||
|
||||
request_messages!(
|
||||
(Auth, AuthResponse),
|
||||
(ShareWorktree, ShareWorktreeResponse),
|
||||
(OpenWorktree, OpenWorktreeResponse),
|
||||
(OpenBuffer, OpenBufferResponse),
|
||||
(SaveBuffer, BufferSaved),
|
||||
(GetChannels, GetChannelsResponse),
|
||||
(GetUsers, GetUsersResponse),
|
||||
(JoinChannel, JoinChannelResponse),
|
||||
(GetUsers, GetUsersResponse)
|
||||
(OpenBuffer, OpenBufferResponse),
|
||||
(OpenWorktree, OpenWorktreeResponse),
|
||||
(SaveBuffer, BufferSaved),
|
||||
(ShareWorktree, ShareWorktreeResponse),
|
||||
);
|
||||
|
||||
pub fn build_typed_envelope(
|
||||
sender_id: ConnectionId,
|
||||
mut envelope: Envelope,
|
||||
) -> Result<Arc<dyn Any + Send + Sync>> {
|
||||
unicast_message_into_typed_envelope(sender_id, &mut envelope)
|
||||
.or_else(|| request_message_into_typed_envelope(sender_id, envelope))
|
||||
.ok_or_else(|| anyhow!("unrecognized payload type"))
|
||||
}
|
||||
entity_messages!(
|
||||
worktree_id,
|
||||
AddPeer,
|
||||
BufferSaved,
|
||||
CloseBuffer,
|
||||
CloseWorktree,
|
||||
OpenBuffer,
|
||||
OpenWorktree,
|
||||
RemovePeer,
|
||||
SaveBuffer,
|
||||
UpdateBuffer,
|
||||
UpdateWorktree,
|
||||
);
|
||||
|
||||
entity_messages!(channel_id, ChannelMessageSent);
|
||||
|
||||
/// A stream of protobuf messages.
|
||||
pub struct MessageStream<S> {
|
||||
|
||||
Reference in New Issue
Block a user