mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-03-18 07:24:07 +01:00
Everything in messages now
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n SELECT\n id, model, workspace_id, request_id, connection_id, created_at, content,\n event_type AS \"event_type!: GrpcEventType\",\n metadata AS \"metadata!: sqlx::types::Json<HashMap<String, String>>\"\n FROM grpc_events\n WHERE connection_id = ?\n ",
|
||||
"query": "\n SELECT\n id, model, workspace_id, request_id, connection_id, created_at, content, status, error,\n event_type AS \"event_type!: GrpcEventType\",\n metadata AS \"metadata!: sqlx::types::Json<HashMap<String, String>>\"\n FROM grpc_events\n WHERE connection_id = ?\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -39,13 +39,23 @@
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "event_type!: GrpcEventType",
|
||||
"name": "status",
|
||||
"ordinal": 7,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "error",
|
||||
"ordinal": 8,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "event_type!: GrpcEventType",
|
||||
"ordinal": 9,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "metadata!: sqlx::types::Json<HashMap<String, String>>",
|
||||
"ordinal": 8,
|
||||
"ordinal": 10,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
@@ -60,9 +70,11 @@
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "737045ddd5f8ba3454425e82b9d3943f93649742d8f78613e01d322745e47ebd"
|
||||
"hash": "18ada3bb42c29f1940ab2e61961d79cdd69210f3dc2076aedcadeba8e34dcb6e"
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n INSERT INTO grpc_events (\n id, workspace_id, request_id, connection_id, content, event_type, metadata\n )\n VALUES (?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT (id) DO UPDATE SET\n updated_at = CURRENT_TIMESTAMP,\n content = excluded.content,\n event_type = excluded.event_type,\n metadata = excluded.metadata\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 7
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "3dce053aef78e831db2369f3c49e891cb8a9e1ba6e7a60fe9e24292a3f97dca3"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n SELECT\n id, model, workspace_id, request_id, connection_id, created_at, content,\n event_type AS \"event_type!: GrpcEventType\",\n metadata AS \"metadata!: sqlx::types::Json<HashMap<String, String>>\"\n FROM grpc_events\n WHERE id = ?\n ",
|
||||
"query": "\n SELECT\n id, model, workspace_id, request_id, connection_id, created_at, content, status, error,\n event_type AS \"event_type!: GrpcEventType\",\n metadata AS \"metadata!: sqlx::types::Json<HashMap<String, String>>\"\n FROM grpc_events\n WHERE id = ?\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -39,13 +39,23 @@
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "event_type!: GrpcEventType",
|
||||
"name": "status",
|
||||
"ordinal": 7,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "error",
|
||||
"ordinal": 8,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "event_type!: GrpcEventType",
|
||||
"ordinal": 9,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "metadata!: sqlx::types::Json<HashMap<String, String>>",
|
||||
"ordinal": 8,
|
||||
"ordinal": 10,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
@@ -60,9 +70,11 @@
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "20d6b878bb8d16bde3e78e22cf801b5b191905d867091bb54a210256a0145a17"
|
||||
"hash": "92d8f003a8f7df692345f2d2fd2504c9222645976e3433e32e190f4ee4bf100d"
|
||||
}
|
||||
12
src-tauri/.sqlx/query-df70bef8eac244eeedd03f5e42573b4c9dbd19cd764e97817c7de30209d21af9.json
generated
Normal file
12
src-tauri/.sqlx/query-df70bef8eac244eeedd03f5e42573b4c9dbd19cd764e97817c7de30209d21af9.json
generated
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n INSERT INTO grpc_events (\n id, workspace_id, request_id, connection_id, content, event_type, metadata, \n status, error\n )\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT (id) DO UPDATE SET\n updated_at = CURRENT_TIMESTAMP,\n content = excluded.content,\n event_type = excluded.event_type,\n metadata = excluded.metadata,\n status = excluded.status,\n error = excluded.error\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 9
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "df70bef8eac244eeedd03f5e42573b4c9dbd19cd764e97817c7de30209d21af9"
|
||||
}
|
||||
@@ -1,67 +1,69 @@
|
||||
CREATE TABLE grpc_requests
|
||||
(
|
||||
id TEXT NOT NULL
|
||||
id TEXT NOT NULL
|
||||
PRIMARY KEY,
|
||||
model TEXT DEFAULT 'grpc_request' NOT NULL,
|
||||
workspace_id TEXT NOT NULL
|
||||
model TEXT DEFAULT 'grpc_request' NOT NULL,
|
||||
workspace_id TEXT NOT NULL
|
||||
REFERENCES workspaces
|
||||
ON DELETE CASCADE,
|
||||
folder_id TEXT NULL
|
||||
folder_id TEXT NULL
|
||||
REFERENCES folders
|
||||
ON DELETE CASCADE,
|
||||
created_at DATETIME DEFAULT(STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')) NOT NULL,
|
||||
updated_at DATETIME DEFAULT(STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')) NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
sort_priority REAL NOT NULL,
|
||||
url TEXT NOT NULL,
|
||||
service TEXT NULL,
|
||||
method TEXT NULL,
|
||||
message TEXT NOT NULL,
|
||||
proto_files TEXT DEFAULT '[]' NOT NULL,
|
||||
authentication TEXT DEFAULT '{}' NOT NULL,
|
||||
authentication_type TEXT NULL,
|
||||
metadata TEXT DEFAULT '[]' NOT NULL
|
||||
created_at DATETIME DEFAULT (STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')) NOT NULL,
|
||||
updated_at DATETIME DEFAULT (STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')) NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
sort_priority REAL NOT NULL,
|
||||
url TEXT NOT NULL,
|
||||
service TEXT NULL,
|
||||
method TEXT NULL,
|
||||
message TEXT NOT NULL,
|
||||
proto_files TEXT DEFAULT '[]' NOT NULL,
|
||||
authentication TEXT DEFAULT '{}' NOT NULL,
|
||||
authentication_type TEXT NULL,
|
||||
metadata TEXT DEFAULT '[]' NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE grpc_connections
|
||||
(
|
||||
id TEXT NOT NULL
|
||||
id TEXT NOT NULL
|
||||
PRIMARY KEY,
|
||||
model TEXT DEFAULT 'grpc_connection' NOT NULL,
|
||||
workspace_id TEXT NOT NULL
|
||||
model TEXT DEFAULT 'grpc_connection' NOT NULL,
|
||||
workspace_id TEXT NOT NULL
|
||||
REFERENCES workspaces
|
||||
ON DELETE CASCADE,
|
||||
request_id TEXT NOT NULL
|
||||
request_id TEXT NOT NULL
|
||||
REFERENCES grpc_requests
|
||||
ON DELETE CASCADE,
|
||||
created_at DATETIME DEFAULT(STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')) NOT NULL,
|
||||
updated_at DATETIME DEFAULT(STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')) NOT NULL,
|
||||
url TEXT NOT NULL,
|
||||
service TEXT NOT NULL,
|
||||
method TEXT NOT NULL,
|
||||
status INTEGER DEFAULT -1 NOT NULL,
|
||||
error TEXT NULL,
|
||||
elapsed INTEGER DEFAULT 0 NOT NULL,
|
||||
trailers TEXT DEFAULT '{}' NOT NULL
|
||||
created_at DATETIME DEFAULT (STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')) NOT NULL,
|
||||
updated_at DATETIME DEFAULT (STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')) NOT NULL,
|
||||
url TEXT NOT NULL,
|
||||
service TEXT NOT NULL,
|
||||
method TEXT NOT NULL,
|
||||
status INTEGER DEFAULT -1 NOT NULL,
|
||||
error TEXT NULL,
|
||||
elapsed INTEGER DEFAULT 0 NOT NULL,
|
||||
trailers TEXT DEFAULT '{}' NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE grpc_events
|
||||
(
|
||||
id TEXT NOT NULL
|
||||
id TEXT NOT NULL
|
||||
PRIMARY KEY,
|
||||
model TEXT DEFAULT 'grpc_event' NOT NULL,
|
||||
workspace_id TEXT NOT NULL
|
||||
model TEXT DEFAULT 'grpc_event' NOT NULL,
|
||||
workspace_id TEXT NOT NULL
|
||||
REFERENCES workspaces
|
||||
ON DELETE CASCADE,
|
||||
request_id TEXT NOT NULL
|
||||
request_id TEXT NOT NULL
|
||||
REFERENCES grpc_requests
|
||||
ON DELETE CASCADE,
|
||||
connection_id TEXT NOT NULL
|
||||
connection_id TEXT NOT NULL
|
||||
REFERENCES grpc_connections
|
||||
ON DELETE CASCADE,
|
||||
created_at DATETIME DEFAULT(STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')) NOT NULL,
|
||||
updated_at DATETIME DEFAULT(STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')) NOT NULL,
|
||||
metadata TEXT DEFAULT '{}' NOT NULL,
|
||||
event_type TEXT NOT NULL,
|
||||
content TEXT NOT NULL
|
||||
created_at DATETIME DEFAULT (STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')) NOT NULL,
|
||||
updated_at DATETIME DEFAULT (STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')) NOT NULL,
|
||||
metadata TEXT DEFAULT '{}' NOT NULL,
|
||||
event_type TEXT NOT NULL,
|
||||
status INTEGER NULL,
|
||||
error TEXT NULL,
|
||||
content TEXT NOT NULL
|
||||
);
|
||||
|
||||
@@ -340,7 +340,7 @@ async fn cmd_grpc_go(
|
||||
|
||||
let grpc_listen = {
|
||||
let w = w.clone();
|
||||
let base_msg = base_msg.clone();
|
||||
let base_event = base_msg.clone();
|
||||
let req = req.clone();
|
||||
let workspace = workspace.clone();
|
||||
let environment = environment.clone();
|
||||
@@ -350,15 +350,14 @@ async fn cmd_grpc_go(
|
||||
req.message
|
||||
};
|
||||
let msg = render::render(&raw_msg, &workspace, environment.as_ref());
|
||||
let conn_id = conn_id.clone();
|
||||
|
||||
upsert_grpc_event(
|
||||
&w,
|
||||
&GrpcEvent {
|
||||
content: format!("Connecting to {}", req.url),
|
||||
event_type: GrpcEventType::Info,
|
||||
event_type: GrpcEventType::ConnectionStart,
|
||||
metadata: Json(metadata.clone()),
|
||||
..base_msg.clone()
|
||||
..base_event.clone()
|
||||
},
|
||||
)
|
||||
.await
|
||||
@@ -405,7 +404,7 @@ async fn cmd_grpc_go(
|
||||
&GrpcEvent {
|
||||
event_type: GrpcEventType::ClientMessage,
|
||||
content: msg,
|
||||
..base_msg.clone()
|
||||
..base_event.clone()
|
||||
},
|
||||
)
|
||||
.await
|
||||
@@ -419,13 +418,13 @@ async fn cmd_grpc_go(
|
||||
&GrpcEvent {
|
||||
metadata: Json(metadata_to_map(msg.metadata().clone())),
|
||||
content: if msg.metadata().len() == 0 {
|
||||
"Connection established"
|
||||
"Received response"
|
||||
} else {
|
||||
"Received metadata"
|
||||
"Received response with metadata"
|
||||
}
|
||||
.to_string(),
|
||||
event_type: GrpcEventType::Info,
|
||||
..base_msg.clone()
|
||||
..base_event.clone()
|
||||
},
|
||||
)
|
||||
.await
|
||||
@@ -435,30 +434,32 @@ async fn cmd_grpc_go(
|
||||
&GrpcEvent {
|
||||
content: serialize_message(&msg.into_inner()).unwrap(),
|
||||
event_type: GrpcEventType::ServerMessage,
|
||||
..base_msg.clone()
|
||||
..base_event.clone()
|
||||
},
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
upsert_grpc_connection(
|
||||
upsert_grpc_event(
|
||||
&w,
|
||||
&GrpcConnection {
|
||||
elapsed: start.elapsed().as_millis() as i64,
|
||||
status: Code::Ok as i64,
|
||||
..get_grpc_connection(&w, &conn_id).await.unwrap().clone()
|
||||
&GrpcEvent {
|
||||
content: "Connection complete".to_string(),
|
||||
event_type: GrpcEventType::ConnectionEnd,
|
||||
status: Some(Code::Ok as i64),
|
||||
..base_event.clone()
|
||||
},
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
Some(Err(e)) => {
|
||||
upsert_grpc_connection(
|
||||
upsert_grpc_event(
|
||||
&w,
|
||||
&GrpcConnection {
|
||||
&GrpcEvent {
|
||||
content: "Failed to connect".to_string(),
|
||||
event_type: GrpcEventType::ConnectionEnd,
|
||||
error: Some(e.to_string()),
|
||||
elapsed: start.elapsed().as_millis() as i64,
|
||||
status: Code::Unknown as i64,
|
||||
..get_grpc_connection(&w, &conn_id).await.unwrap().clone()
|
||||
status: Some(Code::Unknown as i64),
|
||||
..base_event.clone()
|
||||
},
|
||||
)
|
||||
.await
|
||||
@@ -470,33 +471,34 @@ async fn cmd_grpc_go(
|
||||
}
|
||||
|
||||
let mut stream = match maybe_stream {
|
||||
Some(Ok(Ok(s))) => {
|
||||
Some(Ok(Ok(stream))) => {
|
||||
upsert_grpc_event(
|
||||
&w,
|
||||
&GrpcEvent {
|
||||
metadata: Json(metadata_to_map(s.metadata().clone())),
|
||||
content: if s.metadata().len() == 0 {
|
||||
"Connection established"
|
||||
metadata: Json(metadata_to_map(stream.metadata().clone())),
|
||||
content: if stream.metadata().len() == 0 {
|
||||
"Received response"
|
||||
} else {
|
||||
"Received metadata"
|
||||
"Received response with metadata"
|
||||
}
|
||||
.to_string(),
|
||||
.to_string(),
|
||||
event_type: GrpcEventType::Info,
|
||||
..base_msg.clone()
|
||||
..base_event.clone()
|
||||
},
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
s.into_inner()
|
||||
.await
|
||||
.unwrap();
|
||||
stream.into_inner()
|
||||
}
|
||||
Some(Ok(Err(e))) => {
|
||||
upsert_grpc_connection(
|
||||
upsert_grpc_event(
|
||||
&w,
|
||||
&GrpcConnection {
|
||||
&GrpcEvent {
|
||||
error: Some(e.message().to_string()),
|
||||
status: e.code() as i64,
|
||||
elapsed: start.elapsed().as_millis() as i64,
|
||||
..get_grpc_connection(&w, &conn_id).await.unwrap().clone()
|
||||
status: Some(e.code() as i64),
|
||||
content: e.code().description().to_string(),
|
||||
event_type: GrpcEventType::ConnectionEnd,
|
||||
..base_event.clone()
|
||||
},
|
||||
)
|
||||
.await
|
||||
@@ -504,13 +506,14 @@ async fn cmd_grpc_go(
|
||||
return;
|
||||
}
|
||||
Some(Err(e)) => {
|
||||
upsert_grpc_connection(
|
||||
upsert_grpc_event(
|
||||
&w,
|
||||
&GrpcConnection {
|
||||
&GrpcEvent {
|
||||
error: Some(e),
|
||||
status: Code::Unknown as i64,
|
||||
elapsed: start.elapsed().as_millis() as i64,
|
||||
..get_grpc_connection(&w, &conn_id).await.unwrap().clone()
|
||||
status: Some(Code::Unknown as i64),
|
||||
content: "Unknown error".to_string(),
|
||||
event_type: GrpcEventType::ConnectionEnd,
|
||||
..base_event.clone()
|
||||
},
|
||||
)
|
||||
.await
|
||||
@@ -529,7 +532,7 @@ async fn cmd_grpc_go(
|
||||
&GrpcEvent {
|
||||
content: message,
|
||||
event_type: GrpcEventType::ServerMessage,
|
||||
..base_msg.clone()
|
||||
..base_event.clone()
|
||||
},
|
||||
)
|
||||
.await
|
||||
@@ -541,13 +544,14 @@ async fn cmd_grpc_go(
|
||||
.await
|
||||
.unwrap_or_default()
|
||||
.unwrap_or_default();
|
||||
upsert_grpc_connection(
|
||||
upsert_grpc_event(
|
||||
&w,
|
||||
&GrpcConnection {
|
||||
elapsed: start.elapsed().as_millis() as i64,
|
||||
status: Code::Unavailable as i64,
|
||||
trailers: Json(metadata_to_map(trailers)),
|
||||
..get_grpc_connection(&w, &conn_id).await.unwrap().clone()
|
||||
&GrpcEvent {
|
||||
content: "Connection complete".to_string(),
|
||||
status: Some(Code::Unavailable as i64),
|
||||
metadata: Json(metadata_to_map(trailers)),
|
||||
event_type: GrpcEventType::ConnectionEnd,
|
||||
..base_event.clone()
|
||||
},
|
||||
)
|
||||
.await
|
||||
@@ -555,13 +559,14 @@ async fn cmd_grpc_go(
|
||||
break;
|
||||
}
|
||||
Err(status) => {
|
||||
upsert_grpc_connection(
|
||||
upsert_grpc_event(
|
||||
&w,
|
||||
&GrpcConnection {
|
||||
elapsed: start.elapsed().as_millis() as i64,
|
||||
status: Code::Unavailable as i64,
|
||||
trailers: Json(metadata_to_map(status.metadata().clone())),
|
||||
..get_grpc_connection(&w, &conn_id).await.unwrap().clone()
|
||||
&GrpcEvent {
|
||||
content: status.to_string(),
|
||||
status: Some(status.code() as i64),
|
||||
metadata: Json(metadata_to_map(status.metadata().clone())),
|
||||
event_type: GrpcEventType::ConnectionEnd,
|
||||
..base_event.clone()
|
||||
},
|
||||
)
|
||||
.await
|
||||
@@ -578,16 +583,32 @@ async fn cmd_grpc_go(
|
||||
let w = w.clone();
|
||||
tokio::select! {
|
||||
_ = grpc_listen => {
|
||||
// upsert_grpc_connection(
|
||||
// &w,
|
||||
// &GrpcConnection{
|
||||
// elapsed: start.elapsed().as_millis() as i64,
|
||||
// status: Code::Ok as i64,
|
||||
// ..conn
|
||||
// },
|
||||
// ).await.unwrap();
|
||||
let events = list_grpc_events(&w, &conn_id)
|
||||
.await
|
||||
.unwrap();
|
||||
let closed_event = events
|
||||
.iter()
|
||||
.find(|e| GrpcEventType::ConnectionEnd == e.event_type);
|
||||
let closed_status = closed_event.and_then(|e| e.status).unwrap_or(Code::Unavailable as i64);
|
||||
upsert_grpc_connection(
|
||||
&w,
|
||||
&GrpcConnection{
|
||||
elapsed: start.elapsed().as_millis() as i64,
|
||||
status: closed_status,
|
||||
..get_grpc_connection(&w, &conn_id).await.unwrap().clone()
|
||||
},
|
||||
).await.unwrap();
|
||||
},
|
||||
_ = cancelled_rx.changed() => {
|
||||
upsert_grpc_event(
|
||||
&w,
|
||||
&GrpcEvent {
|
||||
content: "Cancelled".to_string(),
|
||||
event_type: GrpcEventType::ConnectionEnd,
|
||||
status: Some(Code::Cancelled as i64),
|
||||
..base_msg.clone()
|
||||
},
|
||||
).await.unwrap();
|
||||
upsert_grpc_connection(
|
||||
&w,
|
||||
&GrpcConnection {
|
||||
|
||||
@@ -237,7 +237,7 @@ pub struct GrpcConnection {
|
||||
pub trailers: Json<HashMap<String, String>>,
|
||||
}
|
||||
|
||||
#[derive(sqlx::Type, Debug, Clone, Serialize, Deserialize)]
|
||||
#[derive(sqlx::Type, Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[sqlx(rename_all = "snake_case")]
|
||||
pub enum GrpcEventType {
|
||||
@@ -245,7 +245,8 @@ pub enum GrpcEventType {
|
||||
Error,
|
||||
ClientMessage,
|
||||
ServerMessage,
|
||||
ConnectionResponse,
|
||||
ConnectionStart,
|
||||
ConnectionEnd,
|
||||
}
|
||||
|
||||
impl Default for GrpcEventType {
|
||||
@@ -266,6 +267,8 @@ pub struct GrpcEvent {
|
||||
pub content: String,
|
||||
pub event_type: GrpcEventType,
|
||||
pub metadata: Json<HashMap<String, String>>,
|
||||
pub status: Option<i64>,
|
||||
pub error: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(sqlx::FromRow, Debug, Clone, Serialize, Deserialize, Default)]
|
||||
@@ -699,32 +702,37 @@ pub async fn list_grpc_connections(
|
||||
|
||||
pub async fn upsert_grpc_event(
|
||||
mgr: &impl Manager<Wry>,
|
||||
message: &GrpcEvent,
|
||||
event: &GrpcEvent,
|
||||
) -> Result<GrpcEvent, sqlx::Error> {
|
||||
let db = get_db(mgr).await;
|
||||
let id = match message.id.as_str() {
|
||||
let id = match event.id.as_str() {
|
||||
"" => generate_id(Some("ge")),
|
||||
_ => message.id.to_string(),
|
||||
_ => event.id.to_string(),
|
||||
};
|
||||
sqlx::query!(
|
||||
r#"
|
||||
INSERT INTO grpc_events (
|
||||
id, workspace_id, request_id, connection_id, content, event_type, metadata
|
||||
id, workspace_id, request_id, connection_id, content, event_type, metadata,
|
||||
status, error
|
||||
)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
ON CONFLICT (id) DO UPDATE SET
|
||||
updated_at = CURRENT_TIMESTAMP,
|
||||
content = excluded.content,
|
||||
event_type = excluded.event_type,
|
||||
metadata = excluded.metadata
|
||||
metadata = excluded.metadata,
|
||||
status = excluded.status,
|
||||
error = excluded.error
|
||||
"#,
|
||||
id,
|
||||
message.workspace_id,
|
||||
message.request_id,
|
||||
message.connection_id,
|
||||
message.content,
|
||||
message.event_type,
|
||||
message.metadata,
|
||||
event.workspace_id,
|
||||
event.request_id,
|
||||
event.connection_id,
|
||||
event.content,
|
||||
event.event_type,
|
||||
event.metadata,
|
||||
event.status,
|
||||
event.error,
|
||||
)
|
||||
.execute(&db)
|
||||
.await?;
|
||||
@@ -744,7 +752,7 @@ pub async fn get_grpc_event(
|
||||
GrpcEvent,
|
||||
r#"
|
||||
SELECT
|
||||
id, model, workspace_id, request_id, connection_id, created_at, content,
|
||||
id, model, workspace_id, request_id, connection_id, created_at, content, status, error,
|
||||
event_type AS "event_type!: GrpcEventType",
|
||||
metadata AS "metadata!: sqlx::types::Json<HashMap<String, String>>"
|
||||
FROM grpc_events
|
||||
@@ -765,7 +773,7 @@ pub async fn list_grpc_events(
|
||||
GrpcEvent,
|
||||
r#"
|
||||
SELECT
|
||||
id, model, workspace_id, request_id, connection_id, created_at, content,
|
||||
id, model, workspace_id, request_id, connection_id, created_at, content, status, error,
|
||||
event_type AS "event_type!: GrpcEventType",
|
||||
metadata AS "metadata!: sqlx::types::Json<HashMap<String, String>>"
|
||||
FROM grpc_events
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import classNames from 'classnames';
|
||||
import { format, addMilliseconds } from 'date-fns';
|
||||
import { format } from 'date-fns';
|
||||
import type { CSSProperties, ReactNode } from 'react';
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import { useGrpcConnections } from '../hooks/useGrpcConnections';
|
||||
@@ -27,48 +27,11 @@ interface Props {
|
||||
| 'no-method';
|
||||
}
|
||||
|
||||
const CONNECTION_RESPONSE_EVENT_ID = 'connection_response';
|
||||
|
||||
export function GrpcConnectionMessagesPane({ style, methodType, activeRequest }: Props) {
|
||||
const [activeEventId, setActiveEventId] = useState<string | null>(null);
|
||||
const connections = useGrpcConnections(activeRequest.id ?? null);
|
||||
const activeConnection = connections[0] ?? null;
|
||||
const ogEvents = useGrpcEvents(activeConnection?.id ?? null);
|
||||
|
||||
const events = useMemo(() => {
|
||||
const createdAt =
|
||||
activeConnection != null &&
|
||||
addMilliseconds(activeConnection.createdAt, activeConnection.elapsed)
|
||||
.toISOString()
|
||||
.replace('Z', '');
|
||||
if (activeConnection == null || activeConnection.elapsed === 0) {
|
||||
return ogEvents;
|
||||
} else if (activeConnection.error != null) {
|
||||
return [
|
||||
...ogEvents,
|
||||
{
|
||||
id: CONNECTION_RESPONSE_EVENT_ID,
|
||||
eventType: 'error',
|
||||
content: activeConnection.error,
|
||||
metadata: activeConnection.trailers,
|
||||
createdAt,
|
||||
updatedAt: createdAt,
|
||||
} as GrpcEvent,
|
||||
];
|
||||
} else {
|
||||
return [
|
||||
...ogEvents,
|
||||
{
|
||||
id: CONNECTION_RESPONSE_EVENT_ID,
|
||||
eventType: activeConnection.status === 0 ? 'connection_response' : 'error',
|
||||
content: `Connection ${GRPC_CODES[activeConnection.status] ?? 'closed'}`,
|
||||
metadata: activeConnection.trailers,
|
||||
createdAt,
|
||||
updatedAt: createdAt,
|
||||
} as GrpcEvent,
|
||||
];
|
||||
}
|
||||
}, [activeConnection, ogEvents]);
|
||||
const events = useGrpcEvents(activeConnection?.id ?? null);
|
||||
|
||||
const activeEvent = useMemo(
|
||||
() => events.find((m) => m.id === activeEventId) ?? null,
|
||||
@@ -110,19 +73,16 @@ export function GrpcConnectionMessagesPane({ style, methodType, activeRequest }:
|
||||
/>
|
||||
</HStack>
|
||||
<div className="overflow-y-auto h-full">
|
||||
{...events.map((m) => (
|
||||
<MessageRow
|
||||
key={m.id}
|
||||
isActive={m.id === activeEventId}
|
||||
eventType={m.eventType}
|
||||
timestamp={m.createdAt}
|
||||
{...events.map((e) => (
|
||||
<EventRow
|
||||
key={e.id}
|
||||
event={e}
|
||||
isActive={e.id === activeEventId}
|
||||
onClick={() => {
|
||||
if (m.id === activeEventId) setActiveEventId(null);
|
||||
else setActiveEventId(m.id);
|
||||
if (e.id === activeEventId) setActiveEventId(null);
|
||||
else setActiveEventId(e.id);
|
||||
}}
|
||||
>
|
||||
{m.content}
|
||||
</MessageRow>
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
@@ -147,11 +107,11 @@ export function GrpcConnectionMessagesPane({ style, methodType, activeRequest }:
|
||||
) : (
|
||||
<div className="h-full grid grid-rows-[auto_minmax(0,1fr)]">
|
||||
<div className="mb-2 select-text cursor-text font-semibold">
|
||||
{activeEvent.content}
|
||||
{activeEvent.error ?? activeEvent.content}
|
||||
</div>
|
||||
{Object.keys(activeEvent.metadata).length === 0 ? (
|
||||
<EmptyStateText>
|
||||
No {activeEvent.eventType === 'connection_response' ? 'trailers' : 'metadata'}
|
||||
No {activeEvent.eventType === 'connection_end' ? 'trailers' : 'metadata'}
|
||||
</EmptyStateText>
|
||||
) : (
|
||||
<KeyValueRows>
|
||||
@@ -170,19 +130,16 @@ export function GrpcConnectionMessagesPane({ style, methodType, activeRequest }:
|
||||
);
|
||||
}
|
||||
|
||||
function MessageRow({
|
||||
function EventRow({
|
||||
onClick,
|
||||
isActive,
|
||||
eventType,
|
||||
children,
|
||||
timestamp,
|
||||
event,
|
||||
}: {
|
||||
onClick?: () => void;
|
||||
isActive?: boolean;
|
||||
eventType: GrpcEvent['eventType'];
|
||||
children: ReactNode;
|
||||
timestamp: string;
|
||||
event: GrpcEvent;
|
||||
}) {
|
||||
const { eventType, status, createdAt, content, error } = event;
|
||||
return (
|
||||
<button
|
||||
onClick={onClick}
|
||||
@@ -199,9 +156,9 @@ function MessageRow({
|
||||
? 'text-blue-600'
|
||||
: eventType === 'client_message'
|
||||
? 'text-violet-600'
|
||||
: eventType === 'error'
|
||||
: eventType === 'error' || (status != null && status > 0)
|
||||
? 'text-orange-600'
|
||||
: eventType === 'connection_response'
|
||||
: eventType === 'connection_end'
|
||||
? 'text-green-600'
|
||||
: 'text-gray-700'
|
||||
}
|
||||
@@ -210,9 +167,9 @@ function MessageRow({
|
||||
? 'Server message'
|
||||
: eventType === 'client_message'
|
||||
? 'Client message'
|
||||
: eventType === 'error'
|
||||
: eventType === 'error' || (status != null && status > 0)
|
||||
? 'Error'
|
||||
: eventType === 'connection_response'
|
||||
: eventType === 'connection_end'
|
||||
? 'Connection response'
|
||||
: undefined
|
||||
}
|
||||
@@ -221,16 +178,16 @@ function MessageRow({
|
||||
? 'arrowBigDownDash'
|
||||
: eventType === 'client_message'
|
||||
? 'arrowBigUpDash'
|
||||
: eventType === 'error'
|
||||
: eventType === 'error' || (status != null && status > 0)
|
||||
? 'alert'
|
||||
: eventType === 'connection_response'
|
||||
: eventType === 'connection_end'
|
||||
? 'check'
|
||||
: 'info'
|
||||
}
|
||||
/>
|
||||
<div className={classNames('w-full truncate text-2xs')}>{children}</div>
|
||||
<div className={classNames('w-full truncate text-2xs')}>{error ?? content}</div>
|
||||
<div className={classNames('opacity-50 text-2xs')}>
|
||||
{format(timestamp + 'Z', 'HH:mm:ss.SSS')}
|
||||
{format(createdAt + 'Z', 'HH:mm:ss.SSS')}
|
||||
</div>
|
||||
</button>
|
||||
);
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
import xmlFormat from 'xml-formatter';
|
||||
|
||||
const INDENT = ' ';
|
||||
|
||||
export function tryFormatJson(text: string, pretty = true): string {
|
||||
if (text === '') return text;
|
||||
|
||||
try {
|
||||
if (pretty) return JSON.stringify(JSON.parse(text), null, 2);
|
||||
if (pretty) return JSON.stringify(JSON.parse(text), null, INDENT);
|
||||
else return JSON.stringify(JSON.parse(text));
|
||||
} catch (_) {
|
||||
return text;
|
||||
@@ -10,8 +14,10 @@ export function tryFormatJson(text: string, pretty = true): string {
|
||||
}
|
||||
|
||||
export function tryFormatXml(text: string): string {
|
||||
if (text === '') return text;
|
||||
|
||||
try {
|
||||
return xmlFormat(text, { throwOnFailure: true, strictMode: false });
|
||||
return xmlFormat(text, { throwOnFailure: true, strictMode: false, indentation: INDENT });
|
||||
} catch (_) {
|
||||
return text;
|
||||
}
|
||||
|
||||
@@ -133,7 +133,15 @@ export interface GrpcEvent extends BaseModel {
|
||||
readonly connectionId: string;
|
||||
readonly model: 'grpc_event';
|
||||
content: string;
|
||||
eventType: 'info' | 'error' | 'client_message' | 'server_message' | 'connection_response';
|
||||
status: number | null;
|
||||
error: string | null;
|
||||
eventType:
|
||||
| 'info'
|
||||
| 'error'
|
||||
| 'client_message'
|
||||
| 'server_message'
|
||||
| 'connection_start'
|
||||
| 'connection_end';
|
||||
metadata: Record<string, string>;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user