Remove remaining instances of router

Co-Authored-By: Nathan Sobo <nathan@zed.dev>
Co-Authored-By: Max Brunsfeld <max@zed.dev>
This commit is contained in:
Antonio Scandurra
2021-08-19 19:38:17 +02:00
co-authored by Nathan Sobo Max Brunsfeld
parent d398b96f56
commit 5338b30c00
12 changed files with 241 additions and 171 deletions
+47 -60
View File
@@ -29,7 +29,7 @@ use tide::{
use time::OffsetDateTime;
use zrpc::{
auth::random_token,
proto::{self, EnvelopedMessage},
proto::{self, AnyTypedEnvelope, EnvelopedMessage},
ConnectionId, Peer, TypedEnvelope,
};
@@ -38,16 +38,12 @@ type ReplicaId = u16;
type MessageHandler = Box<
dyn Send
+ Sync
+ Fn(
&mut Option<Box<dyn Any + Send + Sync>>,
Arc<Server>,
) -> Option<BoxFuture<'static, tide::Result<()>>>,
+ Fn(Box<dyn AnyTypedEnvelope>, Arc<Server>) -> BoxFuture<'static, tide::Result<()>>,
>;
#[derive(Default)]
struct ServerBuilder {
handlers: Vec<MessageHandler>,
handler_types: HashSet<TypeId>,
handlers: HashMap<TypeId, MessageHandler>,
}
impl ServerBuilder {
@@ -57,24 +53,17 @@ impl ServerBuilder {
Fut: 'static + Send + Future<Output = tide::Result<()>>,
M: EnvelopedMessage,
{
if self.handler_types.insert(TypeId::of::<M>()) {
let prev_handler = self.handlers.insert(
TypeId::of::<M>(),
Box::new(move |envelope, server| {
let envelope = envelope.into_any().downcast::<TypedEnvelope<M>>().unwrap();
(handler)(envelope, server).boxed()
}),
);
if prev_handler.is_some() {
panic!("registered a handler for the same message twice");
}
self.handlers
.push(Box::new(move |untyped_envelope, server| {
if let Some(typed_envelope) = untyped_envelope.take() {
match typed_envelope.downcast::<TypedEnvelope<M>>() {
Ok(typed_envelope) => Some((handler)(typed_envelope, server).boxed()),
Err(envelope) => {
*untyped_envelope = Some(envelope);
None
}
}
} else {
None
}
}));
self
}
@@ -90,16 +79,17 @@ impl ServerBuilder {
pub struct Server {
rpc: Arc<Peer>,
state: Arc<AppState>,
handlers: Vec<MessageHandler>,
handlers: HashMap<TypeId, MessageHandler>,
}
impl Server {
pub async fn handle_connection<Conn>(
pub fn handle_connection<Conn>(
self: &Arc<Self>,
connection: Conn,
addr: String,
user_id: UserId,
) where
) -> impl Future<Output = ()>
where
Conn: 'static
+ futures::Sink<WebSocketMessage, Error = WebSocketError>
+ futures::Stream<Item = Result<WebSocketMessage, WebSocketError>>
@@ -107,54 +97,51 @@ impl Server {
+ Unpin,
{
let this = self.clone();
let (connection_id, handle_io, mut incoming_rx) = this.rpc.add_connection(connection).await;
this.state
.rpc
.write()
.await
.add_connection(connection_id, user_id);
async move {
let (connection_id, handle_io, mut incoming_rx) =
this.rpc.add_connection(connection).await;
this.state
.rpc
.write()
.await
.add_connection(connection_id, user_id);
let handle_io = handle_io.fuse();
futures::pin_mut!(handle_io);
loop {
let next_message = incoming_rx.recv().fuse();
futures::pin_mut!(next_message);
futures::select_biased! {
message = next_message => {
if let Some(message) = message {
let start_time = Instant::now();
log::info!("RPC message received");
let mut message = Some(message);
for handler in &this.handlers {
if let Some(future) = (handler)(&mut message, this.clone()) {
if let Err(err) = future.await {
let handle_io = handle_io.fuse();
futures::pin_mut!(handle_io);
loop {
let next_message = incoming_rx.recv().fuse();
futures::pin_mut!(next_message);
futures::select_biased! {
message = next_message => {
if let Some(message) = message {
let start_time = Instant::now();
log::info!("RPC message received: {}", message.payload_type_name());
if let Some(handler) = this.handlers.get(&message.payload_type_id()) {
if let Err(err) = (handler)(message, this.clone()).await {
log::error!("error handling message: {:?}", err);
} else {
log::info!("RPC message handled. duration:{:?}", start_time.elapsed());
}
break;
} else {
log::warn!("unhandled message: {}", message.payload_type_name());
}
} else {
log::info!("rpc connection closed {:?}", addr);
break;
}
if let Some(message) = message {
log::warn!("unhandled message: {:?}", message);
}
handle_io = handle_io => {
if let Err(err) = handle_io {
log::error!("error handling rpc connection {:?} - {:?}", addr, err);
}
} else {
log::info!("rpc connection closed {:?}", addr);
break;
}
}
handle_io = handle_io => {
if let Err(err) = handle_io {
log::error!("error handling rpc connection {:?} - {:?}", addr, err);
}
break;
}
}
}
if let Err(err) = this.rpc.sign_out(connection_id, &this.state).await {
log::error!("error signing out connection {:?} - {:?}", addr, err);
if let Err(err) = this.rpc.sign_out(connection_id, &this.state).await {
log::error!("error signing out connection {:?} - {:?}", addr, err);
}
}
}
}
+15 -24
View File
@@ -1,9 +1,7 @@
use crate::{
auth,
db::{self, UserId},
github,
rpc::{self, build_server},
AppState, Config,
github, rpc, AppState, Config,
};
use async_std::task;
use gpui::TestAppContext;
@@ -28,6 +26,8 @@ use zrpc::Peer;
#[gpui::test]
async fn test_share_worktree(mut cx_a: TestAppContext, mut cx_b: TestAppContext) {
tide::log::start();
let (window_b, _) = cx_b.add_window(|_| EmptyView);
let settings = settings::channel(&cx_b.font_cache()).unwrap().1;
let lang_registry = Arc::new(LanguageRegistry::new());
@@ -514,9 +514,9 @@ async fn test_basic_chat(mut cx_a: TestAppContext, cx_b: TestAppContext) {
.await
.unwrap();
let channels_a = client_a.get_channels().await;
assert_eq!(channels_a.len(), 1);
assert_eq!(channels_a[0].read(&cx_a).name(), "test-channel");
// let channels_a = client_a.get_channels().await;
// assert_eq!(channels_a.len(), 1);
// assert_eq!(channels_a[0].read(&cx_a).name(), "test-channel");
// assert_eq!(
// db.get_recent_channel_messages(channel_id, 50)
@@ -530,8 +530,8 @@ async fn test_basic_chat(mut cx_a: TestAppContext, cx_b: TestAppContext) {
struct TestServer {
peer: Arc<Peer>,
app_state: Arc<AppState>,
server: Arc<rpc::Server>,
db_name: String,
router: Arc<Router>,
}
impl TestServer {
@@ -540,36 +540,27 @@ impl TestServer {
let db_name = format!("zed-test-{}", rng.gen::<u128>());
let app_state = Self::build_app_state(&db_name).await;
let peer = Peer::new();
let mut router = Router::new();
build_server(&mut router, &app_state, &peer);
let server = rpc::build_server(&app_state, &peer);
Self {
peer,
router: Arc::new(router),
app_state,
server,
db_name,
}
}
async fn create_client(&mut self, cx: &mut TestAppContext, name: &str) -> (UserId, Client) {
let user_id = self.app_state.db.create_user(name, false).await.unwrap();
let lang_registry = Arc::new(LanguageRegistry::new());
let client = Client::new(lang_registry.clone());
let mut client_router = ForegroundRouter::new();
cx.update(|cx| zed::worktree::init(cx, &client, &mut client_router));
let client = Client::new();
let (client_conn, server_conn) = Channel::bidirectional();
cx.background()
.spawn(rpc::handle_connection(
self.peer.clone(),
self.router.clone(),
self.app_state.clone(),
name.to_string(),
server_conn,
user_id,
))
.spawn(
self.server
.handle_connection(server_conn, name.to_string(), user_id),
)
.detach();
client
.add_connection(client_conn, Arc::new(client_router), cx.to_async())
.add_connection(client_conn, cx.to_async())
.await
.unwrap();