mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-01-11 22:40:26 +01:00
Fix gRPC stream panic: use async stream combinators instead of block_on
The gRPC streaming code was using tokio::runtime::Handle::current().block_on()
inside filter_map closures, which caused a panic ('Cannot start a runtime from
within a runtime') when called from an async context.
Fixed by replacing the pattern with .then(async move { ... }).filter_map(|x| x)
which properly handles async operations in stream pipelines.
This fixes the gRPC Ping/Pong freeze issue and restores request cancellation.
This commit is contained in:
@@ -392,7 +392,7 @@ async fn cmd_grpc_go<R: Runtime>(
|
|||||||
let encryption_manager = encryption_manager.clone();
|
let encryption_manager = encryption_manager.clone();
|
||||||
let msg = block_in_place(|| {
|
let msg = block_in_place(|| {
|
||||||
tauri::async_runtime::block_on(async {
|
tauri::async_runtime::block_on(async {
|
||||||
render_template(
|
let result = render_template(
|
||||||
msg.as_str(),
|
msg.as_str(),
|
||||||
environment_chain,
|
environment_chain,
|
||||||
&PluginTemplateCallback::new(
|
&PluginTemplateCallback::new(
|
||||||
@@ -406,8 +406,8 @@ async fn cmd_grpc_go<R: Runtime>(
|
|||||||
),
|
),
|
||||||
&RenderOptions { error_behavior: RenderErrorBehavior::Throw },
|
&RenderOptions { error_behavior: RenderErrorBehavior::Throw },
|
||||||
)
|
)
|
||||||
.await
|
.await;
|
||||||
.expect("Failed to render template")
|
result.expect("Failed to render template")
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
in_msg_tx.try_send(msg.clone()).unwrap();
|
in_msg_tx.try_send(msg.clone()).unwrap();
|
||||||
|
|||||||
@@ -131,31 +131,33 @@ impl GrpcConnection {
|
|||||||
let md = metadata.clone();
|
let md = metadata.clone();
|
||||||
let use_reflection = self.use_reflection.clone();
|
let use_reflection = self.use_reflection.clone();
|
||||||
let client_cert = client_cert.clone();
|
let client_cert = client_cert.clone();
|
||||||
stream.filter_map(move |json| {
|
stream
|
||||||
let pool = pool.clone();
|
.then(move |json| {
|
||||||
let uri = uri.clone();
|
let pool = pool.clone();
|
||||||
let input_message = input_message.clone();
|
let uri = uri.clone();
|
||||||
let md = md.clone();
|
let input_message = input_message.clone();
|
||||||
let use_reflection = use_reflection.clone();
|
let md = md.clone();
|
||||||
let client_cert = client_cert.clone();
|
let use_reflection = use_reflection.clone();
|
||||||
tokio::runtime::Handle::current().block_on(async move {
|
let client_cert = client_cert.clone();
|
||||||
if use_reflection {
|
async move {
|
||||||
if let Err(e) =
|
if use_reflection {
|
||||||
reflect_types_for_message(pool, &uri, &json, &md, client_cert).await
|
if let Err(e) =
|
||||||
{
|
reflect_types_for_message(pool, &uri, &json, &md, client_cert).await
|
||||||
warn!("Failed to resolve Any types: {e}");
|
{
|
||||||
|
warn!("Failed to resolve Any types: {e}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
let mut de = Deserializer::from_str(&json);
|
||||||
let mut de = Deserializer::from_str(&json);
|
match DynamicMessage::deserialize(input_message, &mut de) {
|
||||||
match DynamicMessage::deserialize(input_message, &mut de) {
|
Ok(m) => Some(m),
|
||||||
Ok(m) => Some(m),
|
Err(e) => {
|
||||||
Err(e) => {
|
warn!("Failed to deserialize message: {e}");
|
||||||
warn!("Failed to deserialize message: {e}");
|
None
|
||||||
None
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
.filter_map(|x| x)
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut client = tonic::client::Grpc::with_origin(self.conn.clone(), self.uri.clone());
|
let mut client = tonic::client::Grpc::with_origin(self.conn.clone(), self.uri.clone());
|
||||||
@@ -185,31 +187,33 @@ impl GrpcConnection {
|
|||||||
let md = metadata.clone();
|
let md = metadata.clone();
|
||||||
let use_reflection = self.use_reflection.clone();
|
let use_reflection = self.use_reflection.clone();
|
||||||
let client_cert = client_cert.clone();
|
let client_cert = client_cert.clone();
|
||||||
stream.filter_map(move |json| {
|
stream
|
||||||
let pool = pool.clone();
|
.then(move |json| {
|
||||||
let uri = uri.clone();
|
let pool = pool.clone();
|
||||||
let input_message = input_message.clone();
|
let uri = uri.clone();
|
||||||
let md = md.clone();
|
let input_message = input_message.clone();
|
||||||
let use_reflection = use_reflection.clone();
|
let md = md.clone();
|
||||||
let client_cert = client_cert.clone();
|
let use_reflection = use_reflection.clone();
|
||||||
tokio::runtime::Handle::current().block_on(async move {
|
let client_cert = client_cert.clone();
|
||||||
if use_reflection {
|
async move {
|
||||||
if let Err(e) =
|
if use_reflection {
|
||||||
reflect_types_for_message(pool, &uri, &json, &md, client_cert).await
|
if let Err(e) =
|
||||||
{
|
reflect_types_for_message(pool, &uri, &json, &md, client_cert).await
|
||||||
warn!("Failed to resolve Any types: {e}");
|
{
|
||||||
|
warn!("Failed to resolve Any types: {e}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
let mut de = Deserializer::from_str(&json);
|
||||||
let mut de = Deserializer::from_str(&json);
|
match DynamicMessage::deserialize(input_message, &mut de) {
|
||||||
match DynamicMessage::deserialize(input_message, &mut de) {
|
Ok(m) => Some(m),
|
||||||
Ok(m) => Some(m),
|
Err(e) => {
|
||||||
Err(e) => {
|
warn!("Failed to deserialize message: {e}");
|
||||||
warn!("Failed to deserialize message: {e}");
|
None
|
||||||
None
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
.filter_map(|x| x)
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut client = tonic::client::Grpc::with_origin(self.conn.clone(), self.uri.clone());
|
let mut client = tonic::client::Grpc::with_origin(self.conn.clone(), self.uri.clone());
|
||||||
|
|||||||
Reference in New Issue
Block a user