From 742dd750411291657ddee4cabbd6d2f6e4ab4aad Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Wed, 25 May 2022 17:42:25 -0600 Subject: [PATCH 1/2] Implement /rpc_server_snapshot endpoint This returns a JSON snapshot of the state of the server --- crates/collab/src/api.rs | 14 +++++++++++--- crates/collab/src/main.rs | 6 ++++++ crates/collab/src/rpc.rs | 26 ++++++++++++++++++++++++++ crates/collab/src/rpc/store.rs | 11 +++++++++-- crates/rpc/src/peer.rs | 18 ++++++++++++++++-- styles/src/styleTree/workspace.ts | 1 - 6 files changed, 68 insertions(+), 8 deletions(-) diff --git a/crates/collab/src/api.rs b/crates/collab/src/api.rs index 67c56e78ee415bf16312f405a27578e6bc011ca8..2b22ca1c16182a101a339018c3f3a1a8876f4a40 100644 --- a/crates/collab/src/api.rs +++ b/crates/collab/src/api.rs @@ -1,7 +1,7 @@ use crate::{ auth, db::{User, UserId}, - rpc::ResultExt, + rpc::{self, ResultExt}, AppState, Error, Result, }; use anyhow::anyhow; @@ -15,11 +15,12 @@ use axum::{ Extension, Json, Router, }; use serde::{Deserialize, Serialize}; +use serde_json::Value; use std::sync::Arc; use tower::ServiceBuilder; use tracing::instrument; -pub fn routes(rpc_server: &Arc, state: Arc) -> Router { +pub fn routes(rpc_server: &Arc, state: Arc) -> Router { Router::new() .route("/users", get(get_users).post(create_user)) .route( @@ -29,6 +30,7 @@ pub fn routes(rpc_server: &Arc, state: Arc) -> Rou .route("/users/:id/access_tokens", post(create_access_token)) .route("/invite_codes/:code", get(get_user_for_invite_code)) .route("/panic", post(trace_panic)) + .route("/rpc_server_snapshot", get(get_rpc_server_snapshot)) .layer( ServiceBuilder::new() .layer(Extension(state)) @@ -84,7 +86,7 @@ struct CreateUserParams { async fn create_user( Json(params): Json, Extension(app): Extension>, - Extension(rpc_server): Extension>, + Extension(rpc_server): Extension>, ) -> Result> { println!("{:?}", params); @@ -177,6 +179,12 @@ async fn trace_panic(panic: Json) -> Result<()> { Ok(()) } +async fn get_rpc_server_snapshot<'a>( + Extension(rpc_server): Extension>, +) -> Result> { + Ok(Json(serde_json::to_value(rpc_server.snapshot().await)?)) +} + #[derive(Deserialize)] struct CreateAccessTokenQueryParams { public_key: String, diff --git a/crates/collab/src/main.rs b/crates/collab/src/main.rs index 617f1f273f8323cd83fa9b117a4cb5a91c93e29a..74401699ca62afbc23273f667494258d955af9e9 100644 --- a/crates/collab/src/main.rs +++ b/crates/collab/src/main.rs @@ -104,6 +104,12 @@ impl From for Error { } } +impl From for Error { + fn from(error: serde_json::Error) -> Self { + Self::Internal(error.into()) + } +} + impl IntoResponse for Error { fn into_response(self) -> axum::response::Response { match self { diff --git a/crates/collab/src/rpc.rs b/crates/collab/src/rpc.rs index ae5f43e34ba71aa151f7f8c8bd36409abe6be4e9..7ea925fce7d8dea824aeb24b6be936f0099655b0 100644 --- a/crates/collab/src/rpc.rs +++ b/crates/collab/src/rpc.rs @@ -33,6 +33,7 @@ use rpc::{ proto::{self, AnyTypedEnvelope, EntityMessage, EnvelopedMessage, RequestMessage}, Connection, ConnectionId, Peer, Receipt, TypedEnvelope, }; +use serde::{Serialize, Serializer}; use std::{ any::TypeId, future::Future, @@ -85,6 +86,7 @@ pub struct Server { notifications: Option>, } + pub trait Executor: Send + Clone { type Sleep: Send + Future; fn spawn_detached>(&self, future: F); @@ -107,6 +109,23 @@ struct StoreWriteGuard<'a> { _not_send: PhantomData>, } +#[derive(Serialize)] +pub struct ServerSnapshot<'a> { + peer: &'a Peer, + #[serde(serialize_with = "serialize_deref")] + store: RwLockReadGuard<'a, Store>, +} + +pub fn serialize_deref(value: &T, serializer: S) -> Result +where + S: Serializer, + T: Deref, + U: Serialize +{ + Serialize::serialize(value.deref(), serializer) +} + + impl Server { pub fn new( app_state: Arc, @@ -1469,6 +1488,13 @@ impl Server { _not_send: PhantomData, } } + + pub async fn snapshot<'a>(self: &'a Arc) -> ServerSnapshot<'a> { + ServerSnapshot { + store: self.store.read().await, + peer: &self.peer + } + } } impl<'a> Deref for StoreReadGuard<'a> { diff --git a/crates/collab/src/rpc/store.rs b/crates/collab/src/rpc/store.rs index 33fa1eb11396fd35fbe6a185593c1625b40a3721..fe9d21879e8c7c0396c6c273f98e87f0ecc4fe45 100644 --- a/crates/collab/src/rpc/store.rs +++ b/crates/collab/src/rpc/store.rs @@ -2,18 +2,21 @@ use crate::db::{self, ChannelId, UserId}; use anyhow::{anyhow, Result}; use collections::{hash_map::Entry, BTreeMap, HashMap, HashSet}; use rpc::{proto, ConnectionId, Receipt}; +use serde::Serialize; use std::{collections::hash_map, mem, path::PathBuf}; use tracing::instrument; -#[derive(Default)] +#[derive(Default, Serialize)] pub struct Store { connections: HashMap, connections_by_user_id: HashMap>, projects: HashMap, + #[serde(skip)] channels: HashMap, next_project_id: u64, } +#[derive(Serialize)] struct ConnectionState { user_id: UserId, projects: HashSet, @@ -21,21 +24,25 @@ struct ConnectionState { channels: HashSet, } +#[derive(Serialize)] pub struct Project { pub host_connection_id: ConnectionId, pub host_user_id: UserId, pub guests: HashMap, + #[serde(skip)] pub join_requests: HashMap>>, pub active_replica_ids: HashSet, pub worktrees: HashMap, pub language_servers: Vec, } -#[derive(Default)] +#[derive(Default, Serialize)] pub struct Worktree { pub root_name: String, pub visible: bool, + #[serde(skip)] pub entries: HashMap, + #[serde(skip)] pub diagnostic_summaries: BTreeMap, pub scan_id: u64, } diff --git a/crates/rpc/src/peer.rs b/crates/rpc/src/peer.rs index 2fcc5dc09bcf3c64a0c4bc608545a51a652607e8..59abf3c8e3f7ed83df51bd8359fb44d95ae1ead5 100644 --- a/crates/rpc/src/peer.rs +++ b/crates/rpc/src/peer.rs @@ -10,6 +10,7 @@ use futures::{ FutureExt, SinkExt, StreamExt, }; use parking_lot::{Mutex, RwLock}; +use serde::{ser::SerializeStruct, Serialize}; use smol_timeout::TimeoutExt; use std::sync::atomic::Ordering::SeqCst; use std::{ @@ -24,7 +25,7 @@ use std::{ }; use tracing::instrument; -#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Serialize)] pub struct ConnectionId(pub u32); impl fmt::Display for ConnectionId { @@ -89,10 +90,12 @@ pub struct Peer { next_connection_id: AtomicU32, } -#[derive(Clone)] +#[derive(Clone, Serialize)] pub struct ConnectionState { + #[serde(skip)] outgoing_tx: mpsc::UnboundedSender, next_message_id: Arc, + #[serde(skip)] response_channels: Arc)>>>>>, } @@ -471,6 +474,17 @@ impl Peer { } } +impl Serialize for Peer { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("Peer", 2)?; + state.serialize_field("connections", &*self.connections.read())?; + state.end() + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/styles/src/styleTree/workspace.ts b/styles/src/styleTree/workspace.ts index b506b3f780c5ba8154927767134d59b84ecca353..261656e62abf9fd6fbf2e5d082d4fc354f5bb1cb 100644 --- a/styles/src/styleTree/workspace.ts +++ b/styles/src/styleTree/workspace.ts @@ -8,7 +8,6 @@ export function workspaceBackground(theme: Theme) { } export default function workspace(theme: Theme) { - const tab = { height: 32, background: workspaceBackground(theme), From 3ac6fc89c158136d01fc3e0cf6ef2a0cfb0f6964 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 26 May 2022 09:34:39 +0200 Subject: [PATCH 2/2] Pretty-print JSON of server snapshot --- Cargo.lock | 30 +++++++++++++++++++++++++----- crates/auto_update/Cargo.toml | 2 +- crates/collab/Cargo.toml | 3 ++- crates/collab/src/api.rs | 8 ++++---- crates/command_palette/Cargo.toml | 2 +- crates/file_finder/Cargo.toml | 2 +- crates/gpui/Cargo.toml | 2 +- crates/picker/Cargo.toml | 2 +- crates/project/Cargo.toml | 2 +- crates/project_panel/Cargo.toml | 2 +- crates/search/Cargo.toml | 2 +- crates/settings/Cargo.toml | 2 +- crates/theme/Cargo.toml | 2 +- crates/util/Cargo.toml | 2 +- crates/workspace/Cargo.toml | 2 +- crates/zed/Cargo.toml | 4 ++-- 16 files changed, 45 insertions(+), 24 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index db5b0bfe41206a80b848b943b04a7e2cc4d99f2c..2be38304384bc0d5a581b6c8be59f8c428564657 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -416,6 +416,25 @@ dependencies = [ "mime", ] +[[package]] +name = "axum-extra" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75330529f6b27544cedc6089108602a056d016df6aa4f2cb24408d840392ef2d" +dependencies = [ + "axum", + "bytes", + "http", + "mime", + "pin-project-lite 0.2.9", + "serde", + "serde_json", + "tower", + "tower-http", + "tower-layer", + "tower-service", +] + [[package]] name = "backtrace" version = "0.3.64" @@ -593,9 +612,9 @@ checksum = "ae44d1a3d5a19df61dd0c8beb138458ac2a53a7ac09eba97d55592540004306b" [[package]] name = "bytes" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040" +checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" [[package]] name = "cache-padded" @@ -841,6 +860,7 @@ dependencies = [ "async-trait", "async-tungstenite", "axum", + "axum-extra", "base64 0.13.0", "clap 3.1.12", "client", @@ -4237,12 +4257,12 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.64" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79" +checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c" dependencies = [ "indexmap", - "itoa 0.4.7", + "itoa 1.0.1", "ryu", "serde", ] diff --git a/crates/auto_update/Cargo.toml b/crates/auto_update/Cargo.toml index 7a00b1d0b17959ea234837349d9756332137f94d..8809eff68335123feecf69118ac1c1606b5e596f 100644 --- a/crates/auto_update/Cargo.toml +++ b/crates/auto_update/Cargo.toml @@ -18,6 +18,6 @@ isahc = "1.7" lazy_static = "1.4" log = "0.4" serde = { version = "1", features = ["derive"] } -serde_json = { version = "1.0.64", features = ["preserve_order"] } +serde_json = { version = "1.0", features = ["preserve_order"] } smol = "1.2.5" tempdir = "0.3.7" diff --git a/crates/collab/Cargo.toml b/crates/collab/Cargo.toml index 5ebde4a37de5cbb7db2fa67f75e56f2c2389fedd..9b40b318c4b9f020bd23d642e1d6122373411fcd 100644 --- a/crates/collab/Cargo.toml +++ b/crates/collab/Cargo.toml @@ -21,6 +21,7 @@ anyhow = "1.0.40" async-trait = "0.1.50" async-tungstenite = "0.16" axum = { version = "0.5", features = ["json", "headers", "ws"] } +axum-extra = { version = "0.3", features = ["erased-json"] } base64 = "0.13" clap = { version = "3.1", features = ["derive"], optional = true } envy = "0.4.2" @@ -70,7 +71,7 @@ ctor = "0.1" env_logger = "0.8" util = { path = "../util" } lazy_static = "1.4" -serde_json = { version = "1.0.64", features = ["preserve_order"] } +serde_json = { version = "1.0", features = ["preserve_order"] } [features] seed-support = ["clap", "lipsum", "reqwest"] diff --git a/crates/collab/src/api.rs b/crates/collab/src/api.rs index 2b22ca1c16182a101a339018c3f3a1a8876f4a40..a3bc9f8deedc02b78a148aaf98c4173f1477ddfc 100644 --- a/crates/collab/src/api.rs +++ b/crates/collab/src/api.rs @@ -14,8 +14,8 @@ use axum::{ routing::{get, post, put}, Extension, Json, Router, }; +use axum_extra::response::ErasedJson; use serde::{Deserialize, Serialize}; -use serde_json::Value; use std::sync::Arc; use tower::ServiceBuilder; use tracing::instrument; @@ -179,10 +179,10 @@ async fn trace_panic(panic: Json) -> Result<()> { Ok(()) } -async fn get_rpc_server_snapshot<'a>( +async fn get_rpc_server_snapshot( Extension(rpc_server): Extension>, -) -> Result> { - Ok(Json(serde_json::to_value(rpc_server.snapshot().await)?)) +) -> Result { + Ok(ErasedJson::pretty(rpc_server.snapshot().await)) } #[derive(Deserialize)] diff --git a/crates/command_palette/Cargo.toml b/crates/command_palette/Cargo.toml index 2a4d27570fc0552fc19ab3a94df2bab8ff03f326..52fd8bbdc7d9176651ab20a9acbab9250b0c5d34 100644 --- a/crates/command_palette/Cargo.toml +++ b/crates/command_palette/Cargo.toml @@ -22,7 +22,7 @@ workspace = { path = "../workspace" } gpui = { path = "../gpui", features = ["test-support"] } editor = { path = "../editor", features = ["test-support"] } project = { path = "../project", features = ["test-support"] } -serde_json = { version = "1.0.64", features = ["preserve_order"] } +serde_json = { version = "1.0", features = ["preserve_order"] } workspace = { path = "../workspace", features = ["test-support"] } ctor = "0.1" env_logger = "0.8" diff --git a/crates/file_finder/Cargo.toml b/crates/file_finder/Cargo.toml index cb85183ef073484c9cec7f3b5f2ad553a53bd992..ca3eb6b429140e5ccf555f6c08ef2ee2625eeee9 100644 --- a/crates/file_finder/Cargo.toml +++ b/crates/file_finder/Cargo.toml @@ -21,7 +21,7 @@ postage = { version = "0.4.1", features = ["futures-traits"] } [dev-dependencies] gpui = { path = "../gpui", features = ["test-support"] } -serde_json = { version = "1.0.64", features = ["preserve_order"] } +serde_json = { version = "1.0", features = ["preserve_order"] } workspace = { path = "../workspace", features = ["test-support"] } ctor = "0.1" env_logger = "0.8" diff --git a/crates/gpui/Cargo.toml b/crates/gpui/Cargo.toml index c426ad869a71dcfd62840a6f8a7c8499b9613650..18d7766453b0de08ebf3c27e127166c5feb95d0e 100644 --- a/crates/gpui/Cargo.toml +++ b/crates/gpui/Cargo.toml @@ -37,7 +37,7 @@ rand = "0.8.3" resvg = "0.14" seahash = "4.1" serde = { version = "1.0.125", features = ["derive"] } -serde_json = "1.0.64" +serde_json = "1.0" smallvec = { version = "1.6", features = ["union"] } smol = "1.2" time = { version = "0.3" } diff --git a/crates/picker/Cargo.toml b/crates/picker/Cargo.toml index 86e657ecad9073dba73d82e7c6d285b0426e79cb..4528f006877f8ff3a8581b8c123e693f743a5484 100644 --- a/crates/picker/Cargo.toml +++ b/crates/picker/Cargo.toml @@ -17,7 +17,7 @@ workspace = { path = "../workspace" } [dev-dependencies] gpui = { path = "../gpui", features = ["test-support"] } -serde_json = { version = "1.0.64", features = ["preserve_order"] } +serde_json = { version = "1.0", features = ["preserve_order"] } workspace = { path = "../workspace", features = ["test-support"] } ctor = "0.1" env_logger = "0.8" diff --git a/crates/project/Cargo.toml b/crates/project/Cargo.toml index 7a3c7c5367f1137962e3bf0262b7b5eacfac4193..d57bb8d671fd608f52e6a54a5bc13030069bb13c 100644 --- a/crates/project/Cargo.toml +++ b/crates/project/Cargo.toml @@ -41,7 +41,7 @@ postage = { version = "0.4.1", features = ["futures-traits"] } rand = "0.8.3" regex = "1.5" serde = { version = "1", features = ["derive"] } -serde_json = { version = "1.0.64", features = ["preserve_order"] } +serde_json = { version = "1.0", features = ["preserve_order"] } sha2 = "0.10" similar = "1.3" smol = "1.2.5" diff --git a/crates/project_panel/Cargo.toml b/crates/project_panel/Cargo.toml index e431db45ddd392f28964e073576d8df1845777c3..257bac21d9c2c43f05378dd3556d0808a63289fc 100644 --- a/crates/project_panel/Cargo.toml +++ b/crates/project_panel/Cargo.toml @@ -23,4 +23,4 @@ unicase = "2.6" editor = { path = "../editor", features = ["test-support"] } gpui = { path = "../gpui", features = ["test-support"] } workspace = { path = "../workspace", features = ["test-support"] } -serde_json = { version = "1.0.64", features = ["preserve_order"] } +serde_json = { version = "1.0", features = ["preserve_order"] } diff --git a/crates/search/Cargo.toml b/crates/search/Cargo.toml index 40cf85d30a9aac4b6d26198103404e8c374dcb00..56c4fff6519405ecb0dcadeed8177c79213f9058 100644 --- a/crates/search/Cargo.toml +++ b/crates/search/Cargo.toml @@ -26,6 +26,6 @@ smallvec = { version = "1.6", features = ["union"] } [dev-dependencies] editor = { path = "../editor", features = ["test-support"] } gpui = { path = "../gpui", features = ["test-support"] } -serde_json = { version = "1.0.64", features = ["preserve_order"] } +serde_json = { version = "1.0", features = ["preserve_order"] } workspace = { path = "../workspace", features = ["test-support"] } unindent = "0.1" diff --git a/crates/settings/Cargo.toml b/crates/settings/Cargo.toml index c26a469b9f023475f8c9e9ad78d6cb85020ff1dc..cd361fc90ff68b20df6ce2162030af88f76f1d61 100644 --- a/crates/settings/Cargo.toml +++ b/crates/settings/Cargo.toml @@ -20,6 +20,6 @@ anyhow = "1.0.38" json_comments = "0.2" schemars = "0.8" serde = { version = "1", features = ["derive", "rc"] } -serde_json = { version = "1.0.64", features = ["preserve_order"] } +serde_json = { version = "1.0", features = ["preserve_order"] } serde_path_to_error = "0.1.4" toml = "0.5" diff --git a/crates/theme/Cargo.toml b/crates/theme/Cargo.toml index bf319e47493bfd0bdcdeb4541d87184ab0a1a798..af4c15b8a0c1615089f301e018516415288b2990 100644 --- a/crates/theme/Cargo.toml +++ b/crates/theme/Cargo.toml @@ -13,6 +13,6 @@ anyhow = "1.0.38" indexmap = "1.6.2" parking_lot = "0.11.1" serde = { version = "1", features = ["derive", "rc"] } -serde_json = { version = "1.0.64", features = ["preserve_order"] } +serde_json = { version = "1.0", features = ["preserve_order"] } serde_path_to_error = "0.1.4" toml = "0.5" diff --git a/crates/util/Cargo.toml b/crates/util/Cargo.toml index a2475f2cdcc1825c6e2c0d8807fa070b2856d264..87ec77d2dfc23ed2f9ef7088ec6363234ff8c24c 100644 --- a/crates/util/Cargo.toml +++ b/crates/util/Cargo.toml @@ -15,6 +15,6 @@ futures = "0.3" log = { version = "0.4.16", features = ["kv_unstable_serde"] } rand = { version = "0.8", optional = true } tempdir = { version = "0.3.7", optional = true } -serde_json = { version = "1.0.64", features = [ +serde_json = { version = "1.0", features = [ "preserve_order", ], optional = true } diff --git a/crates/workspace/Cargo.toml b/crates/workspace/Cargo.toml index 4260174644cce5dbbee876829c95023855ec0178..106a8c32a7cb6682bd54de2a39711e7798adcde2 100644 --- a/crates/workspace/Cargo.toml +++ b/crates/workspace/Cargo.toml @@ -26,7 +26,7 @@ log = { version = "0.4.16", features = ["kv_unstable_serde"] } parking_lot = "0.11.1" postage = { version = "0.4.1", features = ["futures-traits"] } serde = { version = "1", features = ["derive", "rc"] } -serde_json = { version = "1", features = ["preserve_order"] } +serde_json = { version = "1.0", features = ["preserve_order"] } smallvec = { version = "1.6", features = ["union"] } [dev-dependencies] diff --git a/crates/zed/Cargo.toml b/crates/zed/Cargo.toml index c934b41e0d318e8d00dbed60479c43f17addae02..525569b86914716cb0467bbcdee08f2adc0c7c53 100644 --- a/crates/zed/Cargo.toml +++ b/crates/zed/Cargo.toml @@ -76,7 +76,7 @@ regex = "1.5" rsa = "0.4" rust-embed = { version = "6.3", features = ["include-exclude"] } serde = { version = "1", features = ["derive"] } -serde_json = { version = "1.0.64", features = ["preserve_order"] } +serde_json = { version = "1.0", features = ["preserve_order"] } serde_path_to_error = "0.1.4" simplelog = "0.9" smallvec = { version = "1.6", features = ["union"] } @@ -107,7 +107,7 @@ settings = { path = "../settings", features = ["test-support"] } util = { path = "../util", features = ["test-support"] } workspace = { path = "../workspace", features = ["test-support"] } env_logger = "0.8" -serde_json = { version = "1.0.64", features = ["preserve_order"] } +serde_json = { version = "1.0", features = ["preserve_order"] } unindent = "0.1.7" [package.metadata.bundle]