mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-04-22 16:58:28 +02:00
Fix DB mutex deadlock
This commit is contained in:
@@ -1,12 +0,0 @@
|
|||||||
{
|
|
||||||
"db_name": "SQLite",
|
|
||||||
"query": "\n INSERT INTO grpc_connections (\n id, workspace_id, request_id, service, method\n )\n VALUES ( ?, ?, ?, ?, ?)\n ON CONFLICT (id) DO UPDATE SET\n updated_at = CURRENT_TIMESTAMP,\n service = excluded.service,\n method = excluded.method\n ",
|
|
||||||
"describe": {
|
|
||||||
"columns": [],
|
|
||||||
"parameters": {
|
|
||||||
"Right": 5
|
|
||||||
},
|
|
||||||
"nullable": []
|
|
||||||
},
|
|
||||||
"hash": "1ad8a2581417acb2d1b06fc2727a452230ff4ecbdfb5be54a034ec7c4fb1cabe"
|
|
||||||
}
|
|
||||||
12
src-tauri/.sqlx/query-f7df06213eff80e2ce5100b77ec244c83de39048e77c5af0b0b5d188d3279ca4.json
generated
Normal file
12
src-tauri/.sqlx/query-f7df06213eff80e2ce5100b77ec244c83de39048e77c5af0b0b5d188d3279ca4.json
generated
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"db_name": "SQLite",
|
||||||
|
"query": "\n INSERT INTO grpc_connections (\n id, workspace_id, request_id, service, method\n )\n VALUES (?, ?, ?, ?, ?)\n ON CONFLICT (id) DO UPDATE SET\n updated_at = CURRENT_TIMESTAMP,\n service = excluded.service,\n method = excluded.method\n ",
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 5
|
||||||
|
},
|
||||||
|
"nullable": []
|
||||||
|
},
|
||||||
|
"hash": "f7df06213eff80e2ce5100b77ec244c83de39048e77c5af0b0b5d188d3279ca4"
|
||||||
|
}
|
||||||
@@ -1,8 +1,6 @@
|
|||||||
use prost_reflect::SerializeOptions;
|
use prost_reflect::SerializeOptions;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use tokio_stream::Stream;
|
|
||||||
use tonic::transport::Uri;
|
use tonic::transport::Uri;
|
||||||
use tonic::IntoRequest;
|
|
||||||
|
|
||||||
use crate::proto::fill_pool;
|
use crate::proto::fill_pool;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use hyper::client::connect::Connect;
|
|
||||||
use hyper::client::HttpConnector;
|
use hyper::client::HttpConnector;
|
||||||
use hyper::Client;
|
use hyper::Client;
|
||||||
use hyper_rustls::HttpsConnector;
|
use hyper_rustls::HttpsConnector;
|
||||||
|
|||||||
@@ -366,7 +366,7 @@ pub async fn send_http_request(
|
|||||||
.await
|
.await
|
||||||
.expect("Failed to update response");
|
.expect("Failed to update response");
|
||||||
if !request.id.is_empty() {
|
if !request.id.is_empty() {
|
||||||
emit_side_effect(app_handle.clone(), "updated_model", &response);
|
emit_side_effect(app_handle.clone(), "upserted_model", &response);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy response to download path, if specified
|
// Copy response to download path, if specified
|
||||||
@@ -399,7 +399,7 @@ pub async fn send_http_request(
|
|||||||
cookie_jar.cookies = json_cookies;
|
cookie_jar.cookies = json_cookies;
|
||||||
match models::upsert_cookie_jar(db, &cookie_jar).await {
|
match models::upsert_cookie_jar(db, &cookie_jar).await {
|
||||||
Ok(updated_jar) => {
|
Ok(updated_jar) => {
|
||||||
emit_side_effect(app_handle, "updated_model", &updated_jar);
|
emit_side_effect(app_handle, "upserted_model", &updated_jar);
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("Failed to update cookie jar: {}", e);
|
error!("Failed to update cookie jar: {}", e);
|
||||||
|
|||||||
@@ -102,16 +102,14 @@ async fn cmd_grpc_call_unary(
|
|||||||
request_id: &str,
|
request_id: &str,
|
||||||
app_handle: AppHandle<Wry>,
|
app_handle: AppHandle<Wry>,
|
||||||
grpc_handle: State<'_, Mutex<GrpcManager>>,
|
grpc_handle: State<'_, Mutex<GrpcManager>>,
|
||||||
db_state: State<'_, Mutex<Pool<Sqlite>>>,
|
|
||||||
) -> Result<GrpcMessage, String> {
|
) -> Result<GrpcMessage, String> {
|
||||||
let db = &*db_state.lock().await;
|
let req = get_grpc_request(&app_handle, request_id)
|
||||||
let req = get_grpc_request(db, request_id)
|
|
||||||
.await
|
.await
|
||||||
.map_err(|e| e.to_string())?;
|
.map_err(|e| e.to_string())?;
|
||||||
let conn = {
|
let conn = {
|
||||||
let req = req.clone();
|
let req = req.clone();
|
||||||
upsert_grpc_connection(
|
upsert_grpc_connection(
|
||||||
db,
|
&app_handle,
|
||||||
&GrpcConnection {
|
&GrpcConnection {
|
||||||
workspace_id: req.workspace_id,
|
workspace_id: req.workspace_id,
|
||||||
request_id: req.id,
|
request_id: req.id,
|
||||||
@@ -127,7 +125,7 @@ async fn cmd_grpc_call_unary(
|
|||||||
let req = req.clone();
|
let req = req.clone();
|
||||||
let conn = conn.clone();
|
let conn = conn.clone();
|
||||||
upsert_grpc_message(
|
upsert_grpc_message(
|
||||||
db,
|
&app_handle,
|
||||||
&GrpcMessage {
|
&GrpcMessage {
|
||||||
workspace_id: req.workspace_id,
|
workspace_id: req.workspace_id,
|
||||||
request_id: req.id,
|
request_id: req.id,
|
||||||
@@ -157,7 +155,7 @@ async fn cmd_grpc_call_unary(
|
|||||||
{
|
{
|
||||||
Ok(msg) => {
|
Ok(msg) => {
|
||||||
upsert_grpc_message(
|
upsert_grpc_message(
|
||||||
db,
|
&app_handle,
|
||||||
&GrpcMessage {
|
&GrpcMessage {
|
||||||
message: msg,
|
message: msg,
|
||||||
workspace_id: req.workspace_id,
|
workspace_id: req.workspace_id,
|
||||||
@@ -178,18 +176,15 @@ async fn cmd_grpc_call_unary(
|
|||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
async fn cmd_grpc_client_streaming(
|
async fn cmd_grpc_client_streaming(
|
||||||
request_id: &str,
|
request_id: &str,
|
||||||
grpc_handle: State<'_, Mutex<GrpcManager>>,
|
|
||||||
app_handle: AppHandle<Wry>,
|
app_handle: AppHandle<Wry>,
|
||||||
db_state: State<'_, Mutex<Pool<Sqlite>>>,
|
|
||||||
) -> Result<GrpcConnection, String> {
|
) -> Result<GrpcConnection, String> {
|
||||||
let db = &*db_state.lock().await;
|
let req = get_grpc_request(&app_handle, request_id)
|
||||||
let req = get_grpc_request(db, request_id)
|
|
||||||
.await
|
.await
|
||||||
.map_err(|e| e.to_string())?;
|
.map_err(|e| e.to_string())?;
|
||||||
let conn = {
|
let conn = {
|
||||||
let req = req.clone();
|
let req = req.clone();
|
||||||
upsert_grpc_connection(
|
upsert_grpc_connection(
|
||||||
db,
|
&app_handle,
|
||||||
&GrpcConnection {
|
&GrpcConnection {
|
||||||
workspace_id: req.workspace_id,
|
workspace_id: req.workspace_id,
|
||||||
request_id: req.id,
|
request_id: req.id,
|
||||||
@@ -204,24 +199,19 @@ async fn cmd_grpc_client_streaming(
|
|||||||
{
|
{
|
||||||
let conn = conn.clone();
|
let conn = conn.clone();
|
||||||
let req = req.clone();
|
let req = req.clone();
|
||||||
let db = db.clone();
|
upsert_grpc_message(
|
||||||
emit_side_effect(
|
&app_handle,
|
||||||
app_handle.clone(),
|
&GrpcMessage {
|
||||||
"created_model",
|
message: "Initiating connection".to_string(),
|
||||||
upsert_grpc_message(
|
workspace_id: req.workspace_id,
|
||||||
&db,
|
request_id: req.id,
|
||||||
&GrpcMessage {
|
connection_id: conn.id,
|
||||||
message: "Initiating connection".to_string(),
|
is_info: true,
|
||||||
workspace_id: req.workspace_id,
|
..Default::default()
|
||||||
request_id: req.id,
|
},
|
||||||
connection_id: conn.id,
|
)
|
||||||
is_info: true,
|
.await
|
||||||
..Default::default()
|
.unwrap();
|
||||||
},
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.expect("Failed to upsert message"),
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let (in_msg_tx, in_msg_rx) = tauri::async_runtime::channel::<String>(16);
|
let (in_msg_tx, in_msg_rx) = tauri::async_runtime::channel::<String>(16);
|
||||||
@@ -277,24 +267,18 @@ async fn cmd_grpc_client_streaming(
|
|||||||
let req = req.clone();
|
let req = req.clone();
|
||||||
let conn = conn.clone();
|
let conn = conn.clone();
|
||||||
tauri::async_runtime::spawn(async move {
|
tauri::async_runtime::spawn(async move {
|
||||||
let db_state = app_handle.state::<Mutex<Pool<Sqlite>>>();
|
upsert_grpc_message(
|
||||||
let db = &*db_state.lock().await;
|
&app_handle,
|
||||||
emit_side_effect(
|
&GrpcMessage {
|
||||||
app_handle.clone(),
|
message: msg,
|
||||||
"created_model",
|
workspace_id: req.workspace_id,
|
||||||
upsert_grpc_message(
|
request_id: req.id,
|
||||||
&db,
|
connection_id: conn.id,
|
||||||
&GrpcMessage {
|
..Default::default()
|
||||||
message: msg,
|
},
|
||||||
workspace_id: req.workspace_id,
|
)
|
||||||
request_id: req.id,
|
.await
|
||||||
connection_id: conn.id,
|
.unwrap();
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.expect("Failed to upsert message"),
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Ok(IncomingMsg::Commit) => {
|
Ok(IncomingMsg::Commit) => {
|
||||||
@@ -318,79 +302,61 @@ async fn cmd_grpc_client_streaming(
|
|||||||
let req = req.clone();
|
let req = req.clone();
|
||||||
async move {
|
async move {
|
||||||
let grpc_handle = app_handle.state::<Mutex<GrpcManager>>();
|
let grpc_handle = app_handle.state::<Mutex<GrpcManager>>();
|
||||||
let db_state = app_handle.state::<Mutex<Pool<Sqlite>>>();
|
|
||||||
let msg = grpc_handle
|
let msg = grpc_handle
|
||||||
.lock()
|
.lock()
|
||||||
.await
|
.await
|
||||||
.client_streaming(&conn.id, uri, &service, &method, in_msg_stream)
|
.client_streaming(&conn.id, uri, &service, &method, in_msg_stream)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let db = &*db_state.lock().await;
|
upsert_grpc_message(
|
||||||
emit_side_effect(
|
&app_handle,
|
||||||
app_handle.clone(),
|
&GrpcMessage {
|
||||||
"created_model",
|
message: msg.to_string(),
|
||||||
upsert_grpc_message(
|
workspace_id: req.workspace_id,
|
||||||
db,
|
request_id: req.id,
|
||||||
&GrpcMessage {
|
connection_id: conn.id,
|
||||||
message: msg.to_string(),
|
is_server: true,
|
||||||
workspace_id: req.workspace_id,
|
..Default::default()
|
||||||
request_id: req.id,
|
},
|
||||||
connection_id: conn.id,
|
)
|
||||||
is_server: true,
|
.await
|
||||||
..Default::default()
|
.unwrap();
|
||||||
},
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.expect("Failed to upsert message"),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
{
|
{
|
||||||
let conn = conn.clone();
|
let conn = conn.clone();
|
||||||
|
let app_handle = app_handle.clone();
|
||||||
tauri::async_runtime::spawn(async move {
|
tauri::async_runtime::spawn(async move {
|
||||||
tokio::select! {
|
tokio::select! {
|
||||||
_ = grpc_listen => {
|
_ = grpc_listen => {
|
||||||
let db_state = app_handle.state::<Mutex<Pool<Sqlite>>>();
|
upsert_grpc_message(
|
||||||
let db = &*db_state.lock().await;
|
&app_handle,
|
||||||
emit_side_effect(
|
&GrpcMessage {
|
||||||
app_handle.clone(),
|
message: "Connection completed".to_string(),
|
||||||
"created_model",
|
workspace_id: req.workspace_id,
|
||||||
upsert_grpc_message(
|
request_id: req.id,
|
||||||
&db,
|
connection_id: conn.id,
|
||||||
&GrpcMessage {
|
is_info: true,
|
||||||
message: "Connection completed".to_string(),
|
..Default::default()
|
||||||
workspace_id: req.workspace_id,
|
},
|
||||||
request_id: req.id,
|
)
|
||||||
connection_id: conn.id,
|
.await.map_err(|e| e.to_string()).unwrap();
|
||||||
is_info: true,
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.expect("Failed to upsert message"),
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
_ = cancelled_rx.changed() => {
|
_ = cancelled_rx.changed() => {
|
||||||
let db_state = app_handle.state::<Mutex<Pool<Sqlite>>>();
|
upsert_grpc_message(
|
||||||
let db = &*db_state.lock().await;
|
&app_handle,
|
||||||
emit_side_effect(
|
&GrpcMessage {
|
||||||
app_handle.clone(),
|
message: "Connection cancelled".to_string(),
|
||||||
"created_model",
|
workspace_id: req.workspace_id,
|
||||||
upsert_grpc_message(
|
request_id: req.id,
|
||||||
&db,
|
connection_id: conn.id,
|
||||||
&GrpcMessage {
|
is_info: true,
|
||||||
message: "Connection cancelled".to_string(),
|
..Default::default()
|
||||||
workspace_id: req.workspace_id,
|
},
|
||||||
request_id: req.id,
|
)
|
||||||
connection_id: conn.id,
|
.await
|
||||||
is_info: true,
|
.map_err(|e| e.to_string()).unwrap();
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.expect("Failed to upsert message"),
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
app_handle.unlisten(event_handler);
|
app_handle.unlisten(event_handler);
|
||||||
@@ -405,16 +371,14 @@ async fn cmd_grpc_streaming(
|
|||||||
request_id: &str,
|
request_id: &str,
|
||||||
app_handle: AppHandle<Wry>,
|
app_handle: AppHandle<Wry>,
|
||||||
grpc_handle: State<'_, Mutex<GrpcManager>>,
|
grpc_handle: State<'_, Mutex<GrpcManager>>,
|
||||||
db_state: State<'_, Mutex<Pool<Sqlite>>>,
|
|
||||||
) -> Result<String, String> {
|
) -> Result<String, String> {
|
||||||
let db = &*db_state.lock().await;
|
let req = get_grpc_request(&app_handle, request_id)
|
||||||
let req = get_grpc_request(db, request_id)
|
|
||||||
.await
|
.await
|
||||||
.map_err(|e| e.to_string())?;
|
.map_err(|e| e.to_string())?;
|
||||||
let conn = {
|
let conn = {
|
||||||
let req = req.clone();
|
let req = req.clone();
|
||||||
upsert_grpc_connection(
|
upsert_grpc_connection(
|
||||||
db,
|
&app_handle,
|
||||||
&GrpcConnection {
|
&GrpcConnection {
|
||||||
workspace_id: req.workspace_id,
|
workspace_id: req.workspace_id,
|
||||||
request_id: req.id,
|
request_id: req.id,
|
||||||
@@ -429,24 +393,19 @@ async fn cmd_grpc_streaming(
|
|||||||
{
|
{
|
||||||
let conn = conn.clone();
|
let conn = conn.clone();
|
||||||
let req = req.clone();
|
let req = req.clone();
|
||||||
let db = db.clone();
|
upsert_grpc_message(
|
||||||
emit_side_effect(
|
&app_handle,
|
||||||
app_handle.clone(),
|
&GrpcMessage {
|
||||||
"created_model",
|
message: "Initiating connection".to_string(),
|
||||||
upsert_grpc_message(
|
workspace_id: req.workspace_id,
|
||||||
&db,
|
request_id: req.id,
|
||||||
&GrpcMessage {
|
connection_id: conn.id,
|
||||||
message: "Initiating connection".to_string(),
|
is_info: true,
|
||||||
workspace_id: req.workspace_id,
|
..Default::default()
|
||||||
request_id: req.id,
|
},
|
||||||
connection_id: conn.id,
|
)
|
||||||
is_info: true,
|
.await
|
||||||
..Default::default()
|
.expect("Failed to upsert message");
|
||||||
},
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.expect("Failed to upsert message"),
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let (in_msg_tx, in_msg_rx) = tauri::async_runtime::channel::<String>(16);
|
let (in_msg_tx, in_msg_rx) = tauri::async_runtime::channel::<String>(16);
|
||||||
@@ -496,24 +455,19 @@ async fn cmd_grpc_streaming(
|
|||||||
let req = req.clone();
|
let req = req.clone();
|
||||||
let conn = conn.clone();
|
let conn = conn.clone();
|
||||||
tauri::async_runtime::spawn(async move {
|
tauri::async_runtime::spawn(async move {
|
||||||
let db_state = app_handle.state::<Mutex<Pool<Sqlite>>>();
|
upsert_grpc_message(
|
||||||
let db = &*db_state.lock().await;
|
&app_handle,
|
||||||
emit_side_effect(
|
&GrpcMessage {
|
||||||
app_handle.clone(),
|
message: msg,
|
||||||
"created_model",
|
workspace_id: req.workspace_id,
|
||||||
upsert_grpc_message(
|
request_id: req.id,
|
||||||
&db,
|
connection_id: conn.id,
|
||||||
&GrpcMessage {
|
..Default::default()
|
||||||
message: msg,
|
},
|
||||||
workspace_id: req.workspace_id,
|
)
|
||||||
request_id: req.id,
|
.await
|
||||||
connection_id: conn.id,
|
.map_err(|e| e.to_string())
|
||||||
..Default::default()
|
.unwrap();
|
||||||
},
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.expect("Failed to upsert message"),
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Ok(IncomingMsg::Cancel) => {
|
Ok(IncomingMsg::Cancel) => {
|
||||||
@@ -539,25 +493,20 @@ async fn cmd_grpc_streaming(
|
|||||||
let item = serde_json::to_string_pretty(&item).unwrap();
|
let item = serde_json::to_string_pretty(&item).unwrap();
|
||||||
let req = req.clone();
|
let req = req.clone();
|
||||||
let conn = conn.clone();
|
let conn = conn.clone();
|
||||||
let db_state = app_handle.state::<Mutex<Pool<Sqlite>>>();
|
upsert_grpc_message(
|
||||||
let db = &*db_state.lock().await;
|
&app_handle,
|
||||||
emit_side_effect(
|
&GrpcMessage {
|
||||||
app_handle.clone(),
|
message: item,
|
||||||
"created_model",
|
workspace_id: req.workspace_id,
|
||||||
upsert_grpc_message(
|
request_id: req.id,
|
||||||
&db,
|
connection_id: conn.id,
|
||||||
&GrpcMessage {
|
is_server: true,
|
||||||
message: item,
|
..Default::default()
|
||||||
workspace_id: req.workspace_id,
|
},
|
||||||
request_id: req.id,
|
)
|
||||||
connection_id: conn.id,
|
.await
|
||||||
is_server: true,
|
.map_err(|e| e.to_string())
|
||||||
..Default::default()
|
.unwrap();
|
||||||
},
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.expect("Failed to upsert message"),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
Some(Err(e)) => {
|
Some(Err(e)) => {
|
||||||
error!("gRPC stream error: {:?}", e);
|
error!("gRPC stream error: {:?}", e);
|
||||||
@@ -575,36 +524,25 @@ async fn cmd_grpc_streaming(
|
|||||||
{
|
{
|
||||||
let conn = conn.clone();
|
let conn = conn.clone();
|
||||||
tauri::async_runtime::spawn(async move {
|
tauri::async_runtime::spawn(async move {
|
||||||
|
let app_handle = app_handle.clone();
|
||||||
tokio::select! {
|
tokio::select! {
|
||||||
_ = grpc_listen => {
|
_ = grpc_listen => {
|
||||||
let db_state = app_handle.state::<Mutex<Pool<Sqlite>>>();
|
upsert_grpc_message(
|
||||||
let db = &*db_state.lock().await;
|
&app_handle,
|
||||||
emit_side_effect(
|
&GrpcMessage {
|
||||||
app_handle.clone(),
|
message: "Connection completed".to_string(),
|
||||||
"created_model",
|
workspace_id: req.workspace_id,
|
||||||
upsert_grpc_message(
|
request_id: req.id,
|
||||||
&db,
|
connection_id: conn.id,
|
||||||
&GrpcMessage {
|
is_info: true,
|
||||||
message: "Connection completed".to_string(),
|
..Default::default()
|
||||||
workspace_id: req.workspace_id,
|
},
|
||||||
request_id: req.id,
|
)
|
||||||
connection_id: conn.id,
|
.await.map_err(|e| e.to_string()).unwrap();
|
||||||
is_info: true,
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.expect("Failed to upsert message"),
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
_ = cancelled_rx.changed() => {
|
_ = cancelled_rx.changed() => {
|
||||||
let db_state = app_handle.state::<Mutex<Pool<Sqlite>>>();
|
|
||||||
let db = &*db_state.lock().await;
|
|
||||||
emit_side_effect(
|
|
||||||
app_handle.clone(),
|
|
||||||
"created_model",
|
|
||||||
upsert_grpc_message(
|
upsert_grpc_message(
|
||||||
&db,
|
&app_handle,
|
||||||
&GrpcMessage {
|
&GrpcMessage {
|
||||||
message: "Connection cancelled".to_string(),
|
message: "Connection cancelled".to_string(),
|
||||||
workspace_id: req.workspace_id,
|
workspace_id: req.workspace_id,
|
||||||
@@ -614,9 +552,7 @@ async fn cmd_grpc_streaming(
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await
|
.await.map_err(|e| e.to_string()).unwrap();
|
||||||
.expect("Failed to upsert message"),
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
app_handle.unlisten(event_handler);
|
app_handle.unlisten(event_handler);
|
||||||
@@ -631,17 +567,15 @@ async fn cmd_grpc_server_streaming(
|
|||||||
request_id: &str,
|
request_id: &str,
|
||||||
app_handle: AppHandle<Wry>,
|
app_handle: AppHandle<Wry>,
|
||||||
grpc_handle: State<'_, Mutex<GrpcManager>>,
|
grpc_handle: State<'_, Mutex<GrpcManager>>,
|
||||||
db_state: State<'_, Mutex<Pool<Sqlite>>>,
|
|
||||||
) -> Result<GrpcConnection, String> {
|
) -> Result<GrpcConnection, String> {
|
||||||
let db = &*db_state.lock().await;
|
let req = get_grpc_request(&app_handle, request_id)
|
||||||
let req = get_grpc_request(db, request_id)
|
|
||||||
.await
|
.await
|
||||||
.map_err(|e| e.to_string())?;
|
.map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
let conn = {
|
let conn = {
|
||||||
let req = req.clone();
|
let req = req.clone();
|
||||||
upsert_grpc_connection(
|
upsert_grpc_connection(
|
||||||
db,
|
&app_handle,
|
||||||
&GrpcConnection {
|
&GrpcConnection {
|
||||||
workspace_id: req.workspace_id,
|
workspace_id: req.workspace_id,
|
||||||
request_id: req.id,
|
request_id: req.id,
|
||||||
@@ -656,23 +590,19 @@ async fn cmd_grpc_server_streaming(
|
|||||||
{
|
{
|
||||||
let req = req.clone();
|
let req = req.clone();
|
||||||
let conn = conn.clone();
|
let conn = conn.clone();
|
||||||
emit_side_effect(
|
upsert_grpc_message(
|
||||||
app_handle.clone(),
|
&app_handle,
|
||||||
"created_model",
|
&GrpcMessage {
|
||||||
upsert_grpc_message(
|
message: "Initiating connection".to_string(),
|
||||||
&db,
|
workspace_id: req.workspace_id,
|
||||||
&GrpcMessage {
|
request_id: req.id,
|
||||||
message: "Initiating connection".to_string(),
|
connection_id: conn.id,
|
||||||
workspace_id: req.workspace_id,
|
is_info: true,
|
||||||
request_id: req.id,
|
..Default::default()
|
||||||
connection_id: conn.id,
|
},
|
||||||
is_info: true,
|
)
|
||||||
..Default::default()
|
.await
|
||||||
},
|
.unwrap();
|
||||||
)
|
|
||||||
.await
|
|
||||||
.expect("Failed to upsert message"),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let (cancelled_tx, mut cancelled_rx) = tokio::sync::watch::channel(false);
|
let (cancelled_tx, mut cancelled_rx) = tokio::sync::watch::channel(false);
|
||||||
@@ -718,7 +648,6 @@ async fn cmd_grpc_server_streaming(
|
|||||||
app_handle.listen_global(format!("grpc_client_msg_{}", conn.id).as_str(), cb);
|
app_handle.listen_global(format!("grpc_client_msg_{}", conn.id).as_str(), cb);
|
||||||
|
|
||||||
let grpc_listen = {
|
let grpc_listen = {
|
||||||
let db = db.clone();
|
|
||||||
let conn_id = conn.clone().id;
|
let conn_id = conn.clone().id;
|
||||||
let app_handle = app_handle.clone();
|
let app_handle = app_handle.clone();
|
||||||
let req = req.clone();
|
let req = req.clone();
|
||||||
@@ -726,11 +655,12 @@ async fn cmd_grpc_server_streaming(
|
|||||||
loop {
|
loop {
|
||||||
let req = req.clone();
|
let req = req.clone();
|
||||||
let conn_id = conn_id.clone();
|
let conn_id = conn_id.clone();
|
||||||
|
let app_handle = app_handle.clone();
|
||||||
match stream.next().await {
|
match stream.next().await {
|
||||||
Some(Ok(item)) => {
|
Some(Ok(item)) => {
|
||||||
let item = serde_json::to_string_pretty(&item).unwrap();
|
let item = serde_json::to_string_pretty(&item).unwrap();
|
||||||
let msg = upsert_grpc_message(
|
upsert_grpc_message(
|
||||||
&db,
|
&app_handle,
|
||||||
&GrpcMessage {
|
&GrpcMessage {
|
||||||
message: item,
|
message: item,
|
||||||
workspace_id: req.workspace_id,
|
workspace_id: req.workspace_id,
|
||||||
@@ -743,7 +673,6 @@ async fn cmd_grpc_server_streaming(
|
|||||||
.await
|
.await
|
||||||
.map_err(|e| e.to_string())
|
.map_err(|e| e.to_string())
|
||||||
.expect("Failed to upsert message");
|
.expect("Failed to upsert message");
|
||||||
emit_side_effect(app_handle.clone(), "created_model", msg);
|
|
||||||
}
|
}
|
||||||
Some(Err(e)) => {
|
Some(Err(e)) => {
|
||||||
error!("gRPC stream error: {:?}", e);
|
error!("gRPC stream error: {:?}", e);
|
||||||
@@ -761,16 +690,12 @@ async fn cmd_grpc_server_streaming(
|
|||||||
{
|
{
|
||||||
let conn = conn.clone();
|
let conn = conn.clone();
|
||||||
let req = req.clone();
|
let req = req.clone();
|
||||||
|
let app_handle = app_handle.clone();
|
||||||
tauri::async_runtime::spawn(async move {
|
tauri::async_runtime::spawn(async move {
|
||||||
tokio::select! {
|
tokio::select! {
|
||||||
_ = grpc_listen => {
|
_ = grpc_listen => {
|
||||||
let db_state = app_handle.state::<Mutex<Pool<Sqlite>>>();
|
|
||||||
let db = &*db_state.lock().await;
|
|
||||||
emit_side_effect(
|
|
||||||
app_handle.clone(),
|
|
||||||
"created_model",
|
|
||||||
upsert_grpc_message(
|
upsert_grpc_message(
|
||||||
&db,
|
&app_handle,
|
||||||
&GrpcMessage {
|
&GrpcMessage {
|
||||||
message: "Connection completed".to_string(),
|
message: "Connection completed".to_string(),
|
||||||
workspace_id: req.workspace_id,
|
workspace_id: req.workspace_id,
|
||||||
@@ -780,18 +705,11 @@ async fn cmd_grpc_server_streaming(
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await
|
.await.unwrap();
|
||||||
.expect("Failed to upsert message"),
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
_ = cancelled_rx.changed() => {
|
_ = cancelled_rx.changed() => {
|
||||||
let db_state = app_handle.state::<Mutex<Pool<Sqlite>>>();
|
|
||||||
let db = &*db_state.lock().await;
|
|
||||||
emit_side_effect(
|
|
||||||
app_handle.clone(),
|
|
||||||
"created_model",
|
|
||||||
upsert_grpc_message(
|
upsert_grpc_message(
|
||||||
&db,
|
&app_handle,
|
||||||
&GrpcMessage {
|
&GrpcMessage {
|
||||||
message: "Connection cancelled".to_string(),
|
message: "Connection cancelled".to_string(),
|
||||||
workspace_id: req.workspace_id,
|
workspace_id: req.workspace_id,
|
||||||
@@ -801,9 +719,7 @@ async fn cmd_grpc_server_streaming(
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await
|
.await.unwrap();
|
||||||
.expect("Failed to upsert message"),
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
app_handle.unlisten(event_handler);
|
app_handle.unlisten(event_handler);
|
||||||
@@ -1076,7 +992,7 @@ async fn response_err(
|
|||||||
response = update_response_if_id(db, &response)
|
response = update_response_if_id(db, &response)
|
||||||
.await
|
.await
|
||||||
.expect("Failed to update response");
|
.expect("Failed to update response");
|
||||||
emit_side_effect(app_handle, "updated_model", &response);
|
emit_side_effect(app_handle, "upserted_model", &response);
|
||||||
Ok(response)
|
Ok(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1136,7 +1052,7 @@ async fn cmd_set_key_value(
|
|||||||
if created {
|
if created {
|
||||||
emit_and_return(&window, "created_model", key_value)
|
emit_and_return(&window, "created_model", key_value)
|
||||||
} else {
|
} else {
|
||||||
emit_and_return(&window, "updated_model", key_value)
|
emit_and_return(&window, "upserted_model", key_value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1166,7 +1082,7 @@ async fn cmd_update_cookie_jar(
|
|||||||
.await
|
.await
|
||||||
.expect("Failed to update cookie jar");
|
.expect("Failed to update cookie jar");
|
||||||
|
|
||||||
emit_and_return(&window, "updated_model", updated)
|
emit_and_return(&window, "upserted_model", updated)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
@@ -1235,11 +1151,10 @@ async fn cmd_create_grpc_request(
|
|||||||
sort_priority: f64,
|
sort_priority: f64,
|
||||||
folder_id: Option<&str>,
|
folder_id: Option<&str>,
|
||||||
window: Window<Wry>,
|
window: Window<Wry>,
|
||||||
db_state: State<'_, Mutex<Pool<Sqlite>>>,
|
app_handle: AppHandle,
|
||||||
) -> Result<GrpcRequest, String> {
|
) -> Result<GrpcRequest, String> {
|
||||||
let db = &*db_state.lock().await;
|
|
||||||
let created = upsert_grpc_request(
|
let created = upsert_grpc_request(
|
||||||
db,
|
&app_handle,
|
||||||
&GrpcRequest {
|
&GrpcRequest {
|
||||||
workspace_id: workspace_id.to_string(),
|
workspace_id: workspace_id.to_string(),
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
@@ -1258,10 +1173,9 @@ async fn cmd_create_grpc_request(
|
|||||||
async fn cmd_duplicate_grpc_request(
|
async fn cmd_duplicate_grpc_request(
|
||||||
id: &str,
|
id: &str,
|
||||||
window: Window<Wry>,
|
window: Window<Wry>,
|
||||||
db_state: State<'_, Mutex<Pool<Sqlite>>>,
|
app_handle: AppHandle,
|
||||||
) -> Result<GrpcRequest, String> {
|
) -> Result<GrpcRequest, String> {
|
||||||
let db = &*db_state.lock().await;
|
let request = duplicate_grpc_request(&app_handle, id)
|
||||||
let request = duplicate_grpc_request(db, id)
|
|
||||||
.await
|
.await
|
||||||
.expect("Failed to duplicate grpc request");
|
.expect("Failed to duplicate grpc request");
|
||||||
emit_and_return(&window, "created_model", request)
|
emit_and_return(&window, "created_model", request)
|
||||||
@@ -1318,7 +1232,7 @@ async fn cmd_update_workspace(
|
|||||||
.await
|
.await
|
||||||
.expect("Failed to update request");
|
.expect("Failed to update request");
|
||||||
|
|
||||||
emit_and_return(&window, "updated_model", updated_workspace)
|
emit_and_return(&window, "upserted_model", updated_workspace)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
@@ -1332,20 +1246,19 @@ async fn cmd_update_environment(
|
|||||||
.await
|
.await
|
||||||
.expect("Failed to update environment");
|
.expect("Failed to update environment");
|
||||||
|
|
||||||
emit_and_return(&window, "updated_model", updated_environment)
|
emit_and_return(&window, "upserted_model", updated_environment)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
async fn cmd_update_grpc_request(
|
async fn cmd_update_grpc_request(
|
||||||
request: GrpcRequest,
|
request: GrpcRequest,
|
||||||
window: Window<Wry>,
|
window: Window<Wry>,
|
||||||
db_state: State<'_, Mutex<Pool<Sqlite>>>,
|
app_handle: AppHandle,
|
||||||
) -> Result<GrpcRequest, String> {
|
) -> Result<GrpcRequest, String> {
|
||||||
let db = &*db_state.lock().await;
|
let updated_request = upsert_grpc_request(&app_handle, &request)
|
||||||
let updated_request = upsert_grpc_request(db, &request)
|
|
||||||
.await
|
.await
|
||||||
.expect("Failed to update grpc request");
|
.expect("Failed to update grpc request");
|
||||||
emit_and_return(&window, "updated_model", updated_request)
|
emit_and_return(&window, "upserted_model", updated_request)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
@@ -1358,7 +1271,7 @@ async fn cmd_update_http_request(
|
|||||||
let updated_request = upsert_http_request(db, request)
|
let updated_request = upsert_http_request(db, request)
|
||||||
.await
|
.await
|
||||||
.expect("Failed to update request");
|
.expect("Failed to update request");
|
||||||
emit_and_return(&window, "updated_model", updated_request)
|
emit_and_return(&window, "upserted_model", updated_request)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
@@ -1434,7 +1347,7 @@ async fn cmd_update_folder(
|
|||||||
let updated_folder = upsert_folder(db, folder)
|
let updated_folder = upsert_folder(db, folder)
|
||||||
.await
|
.await
|
||||||
.expect("Failed to update request");
|
.expect("Failed to update request");
|
||||||
emit_and_return(&window, "updated_model", updated_folder)
|
emit_and_return(&window, "upserted_model", updated_folder)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
@@ -1540,7 +1453,7 @@ async fn cmd_update_settings(
|
|||||||
.await
|
.await
|
||||||
.expect("Failed to update settings");
|
.expect("Failed to update settings");
|
||||||
|
|
||||||
emit_and_return(&window, "updated_model", updated_settings)
|
emit_and_return(&window, "upserted_model", updated_settings)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
@@ -1553,12 +1466,10 @@ async fn cmd_get_folder(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
async fn cmd_get_grpc_request(
|
async fn cmd_get_grpc_request(id: &str, app_handle: AppHandle<Wry>) -> Result<GrpcRequest, String> {
|
||||||
id: &str,
|
get_grpc_request(&app_handle, id)
|
||||||
db_state: State<'_, Mutex<Pool<Sqlite>>>,
|
.await
|
||||||
) -> Result<GrpcRequest, String> {
|
.map_err(|e| e.to_string())
|
||||||
let db = &*db_state.lock().await;
|
|
||||||
get_grpc_request(db, id).await.map_err(|e| e.to_string())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ use serde::{Deserialize, Serialize};
|
|||||||
use sqlx::types::chrono::NaiveDateTime;
|
use sqlx::types::chrono::NaiveDateTime;
|
||||||
use sqlx::types::{Json, JsonValue};
|
use sqlx::types::{Json, JsonValue};
|
||||||
use sqlx::{Pool, Sqlite};
|
use sqlx::{Pool, Sqlite};
|
||||||
use tauri::AppHandle;
|
use tauri::{AppHandle, Manager};
|
||||||
|
use tokio::sync::Mutex;
|
||||||
|
|
||||||
fn default_true() -> bool {
|
fn default_true() -> bool {
|
||||||
true
|
true
|
||||||
@@ -457,18 +458,19 @@ pub async fn delete_cookie_jar(db: &Pool<Sqlite>, id: &str) -> Result<CookieJar,
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn duplicate_grpc_request(
|
pub async fn duplicate_grpc_request(
|
||||||
db: &Pool<Sqlite>,
|
app_handle: &AppHandle,
|
||||||
id: &str,
|
id: &str,
|
||||||
) -> Result<GrpcRequest, sqlx::Error> {
|
) -> Result<GrpcRequest, sqlx::Error> {
|
||||||
let mut request = get_grpc_request(db, id).await?.clone();
|
let mut request = get_grpc_request(app_handle, id).await?.clone();
|
||||||
request.id = "".to_string();
|
request.id = "".to_string();
|
||||||
upsert_grpc_request(db, &request).await
|
upsert_grpc_request(app_handle, &request).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn upsert_grpc_request(
|
pub async fn upsert_grpc_request(
|
||||||
db: &Pool<Sqlite>,
|
app_handle: &AppHandle,
|
||||||
request: &GrpcRequest,
|
request: &GrpcRequest,
|
||||||
) -> Result<GrpcRequest, sqlx::Error> {
|
) -> Result<GrpcRequest, sqlx::Error> {
|
||||||
|
let db = get_db(app_handle).await;
|
||||||
let id = match request.id.as_str() {
|
let id = match request.id.as_str() {
|
||||||
"" => generate_id(Some("gr")),
|
"" => generate_id(Some("gr")),
|
||||||
_ => request.id.to_string(),
|
_ => request.id.to_string(),
|
||||||
@@ -500,13 +502,19 @@ pub async fn upsert_grpc_request(
|
|||||||
request.method,
|
request.method,
|
||||||
request.message,
|
request.message,
|
||||||
)
|
)
|
||||||
.execute(db)
|
.execute(&db)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
get_grpc_request(db, &id).await
|
get_grpc_request(app_handle, &id).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_grpc_request(db: &Pool<Sqlite>, id: &str) -> Result<GrpcRequest, sqlx::Error> {
|
pub async fn get_grpc_request(
|
||||||
|
app_handle: &AppHandle,
|
||||||
|
id: &str,
|
||||||
|
) -> Result<GrpcRequest, sqlx::Error> {
|
||||||
|
let db_state = app_handle.state::<Mutex<Pool<Sqlite>>>();
|
||||||
|
let db = &*db_state.lock().await;
|
||||||
|
|
||||||
sqlx::query_as!(
|
sqlx::query_as!(
|
||||||
GrpcRequest,
|
GrpcRequest,
|
||||||
r#"
|
r#"
|
||||||
@@ -542,9 +550,10 @@ pub async fn list_grpc_requests(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn upsert_grpc_connection(
|
pub async fn upsert_grpc_connection(
|
||||||
db: &Pool<Sqlite>,
|
app_handle: &AppHandle,
|
||||||
connection: &GrpcConnection,
|
connection: &GrpcConnection,
|
||||||
) -> Result<GrpcConnection, sqlx::Error> {
|
) -> Result<GrpcConnection, sqlx::Error> {
|
||||||
|
let db = get_db(&app_handle).await;
|
||||||
let id = match connection.id.as_str() {
|
let id = match connection.id.as_str() {
|
||||||
"" => generate_id(Some("gc")),
|
"" => generate_id(Some("gc")),
|
||||||
_ => connection.id.to_string(),
|
_ => connection.id.to_string(),
|
||||||
@@ -554,7 +563,7 @@ pub async fn upsert_grpc_connection(
|
|||||||
INSERT INTO grpc_connections (
|
INSERT INTO grpc_connections (
|
||||||
id, workspace_id, request_id, service, method
|
id, workspace_id, request_id, service, method
|
||||||
)
|
)
|
||||||
VALUES ( ?, ?, ?, ?, ?)
|
VALUES (?, ?, ?, ?, ?)
|
||||||
ON CONFLICT (id) DO UPDATE SET
|
ON CONFLICT (id) DO UPDATE SET
|
||||||
updated_at = CURRENT_TIMESTAMP,
|
updated_at = CURRENT_TIMESTAMP,
|
||||||
service = excluded.service,
|
service = excluded.service,
|
||||||
@@ -566,16 +575,17 @@ pub async fn upsert_grpc_connection(
|
|||||||
connection.service,
|
connection.service,
|
||||||
connection.method,
|
connection.method,
|
||||||
)
|
)
|
||||||
.execute(db)
|
.execute(&db)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
get_grpc_connection(db, &id).await
|
get_grpc_connection(app_handle, &id).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_grpc_connection(
|
pub async fn get_grpc_connection(
|
||||||
db: &Pool<Sqlite>,
|
app_handle: &AppHandle,
|
||||||
id: &str,
|
id: &str,
|
||||||
) -> Result<GrpcConnection, sqlx::Error> {
|
) -> Result<GrpcConnection, sqlx::Error> {
|
||||||
|
let db = get_db(&app_handle).await;
|
||||||
sqlx::query_as!(
|
sqlx::query_as!(
|
||||||
GrpcConnection,
|
GrpcConnection,
|
||||||
r#"
|
r#"
|
||||||
@@ -585,7 +595,7 @@ pub async fn get_grpc_connection(
|
|||||||
"#,
|
"#,
|
||||||
id,
|
id,
|
||||||
)
|
)
|
||||||
.fetch_one(db)
|
.fetch_one(&db)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -608,9 +618,10 @@ pub async fn list_grpc_connections(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn upsert_grpc_message(
|
pub async fn upsert_grpc_message(
|
||||||
db: &Pool<Sqlite>,
|
app_handle: &AppHandle,
|
||||||
message: &GrpcMessage,
|
message: &GrpcMessage,
|
||||||
) -> Result<GrpcMessage, sqlx::Error> {
|
) -> Result<GrpcMessage, sqlx::Error> {
|
||||||
|
let db = get_db(app_handle).await;
|
||||||
let id = match message.id.as_str() {
|
let id = match message.id.as_str() {
|
||||||
"" => generate_id(Some("gm")),
|
"" => generate_id(Some("gm")),
|
||||||
_ => message.id.to_string(),
|
_ => message.id.to_string(),
|
||||||
@@ -635,13 +646,21 @@ pub async fn upsert_grpc_message(
|
|||||||
message.is_server,
|
message.is_server,
|
||||||
message.is_info,
|
message.is_info,
|
||||||
)
|
)
|
||||||
.execute(db)
|
.execute(&db)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
get_grpc_message(db, &id).await
|
let msg = get_grpc_message(app_handle, &id).await;
|
||||||
|
match msg {
|
||||||
|
Ok(msg) => Ok(emit_upserted_model(app_handle, msg.clone()).await),
|
||||||
|
Err(e) => Err(e),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_grpc_message(db: &Pool<Sqlite>, id: &str) -> Result<GrpcMessage, sqlx::Error> {
|
pub async fn get_grpc_message(
|
||||||
|
app_handle: &AppHandle,
|
||||||
|
id: &str,
|
||||||
|
) -> Result<GrpcMessage, sqlx::Error> {
|
||||||
|
let db = get_db(app_handle).await;
|
||||||
sqlx::query_as!(
|
sqlx::query_as!(
|
||||||
GrpcMessage,
|
GrpcMessage,
|
||||||
r#"
|
r#"
|
||||||
@@ -653,7 +672,7 @@ pub async fn get_grpc_message(db: &Pool<Sqlite>, id: &str) -> Result<GrpcMessage
|
|||||||
"#,
|
"#,
|
||||||
id,
|
id,
|
||||||
)
|
)
|
||||||
.fetch_one(db)
|
.fetch_one(&db)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1327,3 +1346,16 @@ pub async fn get_workspace_export_resources(
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn emit_upserted_model<S: Serialize + Clone>(app_handle: &AppHandle, model: S) -> S {
|
||||||
|
app_handle
|
||||||
|
.emit_all("upserted_model", model.clone())
|
||||||
|
.unwrap();
|
||||||
|
model
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_db(app_handle: &AppHandle) -> Pool<Sqlite> {
|
||||||
|
let db_state = app_handle.state::<Mutex<Pool<Sqlite>>>();
|
||||||
|
let db = &*db_state.lock().await;
|
||||||
|
db.clone()
|
||||||
|
}
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ export function GlobalHooks() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
useListenToTauriEvent<Model>('updated_model', ({ payload, windowLabel }) => {
|
useListenToTauriEvent<Model>('upserted_model', ({ payload, windowLabel }) => {
|
||||||
if (shouldIgnoreEvent(payload, windowLabel)) return;
|
if (shouldIgnoreEvent(payload, windowLabel)) return;
|
||||||
|
|
||||||
const queryKey =
|
const queryKey =
|
||||||
@@ -119,12 +119,21 @@ export function GlobalHooks() {
|
|||||||
wasUpdatedExternally(payload.id);
|
wasUpdatedExternally(payload.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const pushToFront = (['http_response', 'grpc_connection'] as Model['model'][]).includes(
|
||||||
|
payload.model,
|
||||||
|
);
|
||||||
|
|
||||||
if (!shouldIgnoreModel(payload)) {
|
if (!shouldIgnoreModel(payload)) {
|
||||||
console.time('set query date');
|
queryClient.setQueryData<Model[]>(queryKey, (values = []) => {
|
||||||
queryClient.setQueryData<Model[]>(queryKey, (values) =>
|
const index = values.findIndex((v) => modelsEq(v, payload)) ?? -1;
|
||||||
values?.map((v) => (modelsEq(v, payload) ? payload : v)),
|
if (index >= 0) {
|
||||||
);
|
console.log('UPDATED MODEL', payload);
|
||||||
console.timeEnd('set query date');
|
return [...values.slice(0, index), payload, ...values.slice(index + 1)];
|
||||||
|
} else {
|
||||||
|
console.log('INSERTED MODEL', payload);
|
||||||
|
return pushToFront ? [payload, ...(values ?? [])] : [...(values ?? []), payload];
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import { RadioDropdown } from './core/RadioDropdown';
|
|||||||
import { Separator } from './core/Separator';
|
import { Separator } from './core/Separator';
|
||||||
import { SplitLayout } from './core/SplitLayout';
|
import { SplitLayout } from './core/SplitLayout';
|
||||||
import { HStack, VStack } from './core/Stacks';
|
import { HStack, VStack } from './core/Stacks';
|
||||||
|
import { StatusTag } from './core/StatusTag';
|
||||||
import { GrpcEditor } from './GrpcEditor';
|
import { GrpcEditor } from './GrpcEditor';
|
||||||
import { UrlBar } from './UrlBar';
|
import { UrlBar } from './UrlBar';
|
||||||
|
|
||||||
@@ -200,22 +201,22 @@ export function GrpcConnectionLayout({ style }: Props) {
|
|||||||
{select.options.find((o) => o.value === select.value)?.label}
|
{select.options.find((o) => o.value === select.value)?.label}
|
||||||
</Button>
|
</Button>
|
||||||
</RadioDropdown>
|
</RadioDropdown>
|
||||||
<IconButton
|
{!grpc.isStreaming && (
|
||||||
className="border border-highlight"
|
<IconButton
|
||||||
size="sm"
|
className="border border-highlight"
|
||||||
title={messageType === 'unary' ? 'Send' : 'Connect'}
|
size="sm"
|
||||||
hotkeyAction={grpc.isStreaming ? undefined : 'http_request.send'}
|
title={messageType === 'unary' ? 'Send' : 'Connect'}
|
||||||
onClick={grpc.isStreaming ? () => grpc.cancel.mutateAsync() : handleConnect}
|
hotkeyAction={grpc.isStreaming ? undefined : 'http_request.send'}
|
||||||
disabled={grpc.isStreaming}
|
onClick={handleConnect}
|
||||||
spin={grpc.isStreaming || grpc.unary.isLoading}
|
icon={
|
||||||
icon={
|
grpc.isStreaming
|
||||||
grpc.isStreaming
|
? 'refresh'
|
||||||
? 'refresh'
|
: messageType === 'unary'
|
||||||
: messageType === 'unary'
|
? 'sendHorizontal'
|
||||||
? 'sendHorizontal'
|
: 'arrowUpDown'
|
||||||
: 'arrowUpDown'
|
}
|
||||||
}
|
/>
|
||||||
/>
|
)}
|
||||||
{grpc.isStreaming && (
|
{grpc.isStreaming && (
|
||||||
<IconButton
|
<IconButton
|
||||||
className="border border-highlight"
|
className="border border-highlight"
|
||||||
@@ -285,39 +286,53 @@ export function GrpcConnectionLayout({ style }: Props) {
|
|||||||
}
|
}
|
||||||
minHeightPx={20}
|
minHeightPx={20}
|
||||||
firstSlot={() => (
|
firstSlot={() => (
|
||||||
<div className="overflow-y-auto w-full">
|
<div className="w-full grid grid-rows-[auto_minmax(0,1fr)]">
|
||||||
{...messages.map((m) => (
|
<HStack className="px-3 mb-2">
|
||||||
<HStack
|
<div className="font-mono">
|
||||||
key={m.id}
|
{grpc.isStreaming ? (
|
||||||
space={2}
|
<HStack alignItems="center" space={2}>
|
||||||
onClick={() => {
|
<Icon icon="refresh" size="sm" spin />
|
||||||
if (m.id === activeMessageId) setActiveMessageId(null);
|
Connected
|
||||||
else setActiveMessageId(m.id);
|
</HStack>
|
||||||
}}
|
) : (
|
||||||
alignItems="center"
|
'Done'
|
||||||
className={classNames(
|
|
||||||
'px-2 py-1 font-mono',
|
|
||||||
m === activeMessage && 'bg-highlight',
|
|
||||||
)}
|
)}
|
||||||
>
|
</div>
|
||||||
<Icon
|
</HStack>
|
||||||
className={
|
<div className="overflow-y-auto h-full">
|
||||||
m.isInfo
|
{...messages.map((m) => (
|
||||||
? 'text-gray-600'
|
<HStack
|
||||||
: m.isServer
|
key={m.id}
|
||||||
? 'text-blue-600'
|
space={2}
|
||||||
: 'text-green-600'
|
onClick={() => {
|
||||||
}
|
if (m.id === activeMessageId) setActiveMessageId(null);
|
||||||
icon={
|
else setActiveMessageId(m.id);
|
||||||
m.isInfo ? 'info' : m.isServer ? 'arrowBigDownDash' : 'arrowBigUpDash'
|
}}
|
||||||
}
|
alignItems="center"
|
||||||
/>
|
className={classNames(
|
||||||
<div className="w-full truncate text-gray-800 text-2xs">{m.message}</div>
|
'px-2 py-1 font-mono',
|
||||||
<div className="text-gray-600 text-2xs">
|
m === activeMessage && 'bg-highlight',
|
||||||
{format(m.createdAt, 'HH:mm:ss')}
|
)}
|
||||||
</div>
|
>
|
||||||
</HStack>
|
<Icon
|
||||||
))}
|
className={
|
||||||
|
m.isInfo
|
||||||
|
? 'text-gray-600'
|
||||||
|
: m.isServer
|
||||||
|
? 'text-blue-600'
|
||||||
|
: 'text-green-600'
|
||||||
|
}
|
||||||
|
icon={
|
||||||
|
m.isInfo ? 'info' : m.isServer ? 'arrowBigDownDash' : 'arrowBigUpDash'
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<div className="w-full truncate text-gray-800 text-2xs">{m.message}</div>
|
||||||
|
<div className="text-gray-600 text-2xs">
|
||||||
|
{format(m.createdAt, 'HH:mm:ss')}
|
||||||
|
</div>
|
||||||
|
</HStack>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
secondSlot={
|
secondSlot={
|
||||||
|
|||||||
Reference in New Issue
Block a user