From 07615f07cc6df1ca9bf772017fdd627e47ba77b9 Mon Sep 17 00:00:00 2001 From: Tony Date: Mon, 19 May 2025 00:17:23 +0800 Subject: [PATCH 1/7] Dynamic dispatch async commands --- crates/tauri-macros/src/command/wrapper.rs | 8 ++++---- crates/tauri/src/ipc/mod.rs | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/crates/tauri-macros/src/command/wrapper.rs b/crates/tauri-macros/src/command/wrapper.rs index 54b3857b06d6..d5fd1d601b7f 100644 --- a/crates/tauri-macros/src/command/wrapper.rs +++ b/crates/tauri-macros/src/command/wrapper.rs @@ -331,22 +331,22 @@ fn body_async( use tracing::Instrument; let span = tracing::debug_span!("ipc::request::run"); - #resolver.respond_async_serialized(async move { + #resolver.respond_async_serialized(Box::pin(async move { let result = $path(#(#args?),*); let kind = (&result).async_kind(); kind.future(result).await } - .instrument(span)); + .instrument(span))); return true; } #[cfg(not(feature = "tracing"))] quote! { - #resolver.respond_async_serialized(async move { + #resolver.respond_async_serialized(Box::pin(async move { let result = $path(#(#args?),*); let kind = (&result).async_kind(); kind.future(result).await - }); + })); return true; } }) diff --git a/crates/tauri/src/ipc/mod.rs b/crates/tauri/src/ipc/mod.rs index ce8d579e2188..5adcabc48469 100644 --- a/crates/tauri/src/ipc/mod.rs +++ b/crates/tauri/src/ipc/mod.rs @@ -6,7 +6,7 @@ //! //! This module includes utilities to send messages to the JS layer of the webview. -use std::sync::{Arc, Mutex}; +use std::{pin::Pin, sync::{Arc, Mutex}}; use futures_util::Future; use http::HeaderMap; @@ -338,10 +338,10 @@ impl InvokeResolver { } /// Reply to the invoke promise with an async task which is already serialized. - pub fn respond_async_serialized(self, task: F) - where - F: Future> + Send + 'static, - { + pub fn respond_async_serialized( + self, + task: Pin> + Send>>, + ) { crate::async_runtime::spawn(async move { let response = match task.await { Ok(ok) => InvokeResponse::Ok(ok), From e2f24f6344c3d4e4c93d72ee2f5d62e69ad8878d Mon Sep 17 00:00:00 2001 From: Tony Date: Mon, 19 May 2025 00:22:39 +0800 Subject: [PATCH 2/7] format --- crates/tauri/src/ipc/mod.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/crates/tauri/src/ipc/mod.rs b/crates/tauri/src/ipc/mod.rs index 5adcabc48469..1a2e2848b5e5 100644 --- a/crates/tauri/src/ipc/mod.rs +++ b/crates/tauri/src/ipc/mod.rs @@ -6,7 +6,10 @@ //! //! This module includes utilities to send messages to the JS layer of the webview. -use std::{pin::Pin, sync::{Arc, Mutex}}; +use std::{ + pin::Pin, + sync::{Arc, Mutex}, +}; use futures_util::Future; use http::HeaderMap; From de15f0559248b50eeb9365912fb27e5b86ae94c2 Mon Sep 17 00:00:00 2001 From: Tony Date: Mon, 19 May 2025 00:32:57 +0800 Subject: [PATCH 3/7] Preserve `'static` --- crates/tauri/src/ipc/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/tauri/src/ipc/mod.rs b/crates/tauri/src/ipc/mod.rs index 1a2e2848b5e5..270833e3a2b5 100644 --- a/crates/tauri/src/ipc/mod.rs +++ b/crates/tauri/src/ipc/mod.rs @@ -343,7 +343,7 @@ impl InvokeResolver { /// Reply to the invoke promise with an async task which is already serialized. pub fn respond_async_serialized( self, - task: Pin> + Send>>, + task: Pin> + Send + 'static>>, ) { crate::async_runtime::spawn(async move { let response = match task.await { From 5f817b98f4c6f0f6a9b852e9e9eac21aefa59e39 Mon Sep 17 00:00:00 2001 From: Tony Date: Mon, 19 May 2025 09:12:42 +0800 Subject: [PATCH 4/7] Use a inner function instead --- crates/tauri-macros/src/command/wrapper.rs | 8 ++++---- crates/tauri/src/ipc/mod.rs | 10 +++++++++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/crates/tauri-macros/src/command/wrapper.rs b/crates/tauri-macros/src/command/wrapper.rs index d5fd1d601b7f..54b3857b06d6 100644 --- a/crates/tauri-macros/src/command/wrapper.rs +++ b/crates/tauri-macros/src/command/wrapper.rs @@ -331,22 +331,22 @@ fn body_async( use tracing::Instrument; let span = tracing::debug_span!("ipc::request::run"); - #resolver.respond_async_serialized(Box::pin(async move { + #resolver.respond_async_serialized(async move { let result = $path(#(#args?),*); let kind = (&result).async_kind(); kind.future(result).await } - .instrument(span))); + .instrument(span)); return true; } #[cfg(not(feature = "tracing"))] quote! { - #resolver.respond_async_serialized(Box::pin(async move { + #resolver.respond_async_serialized(async move { let result = $path(#(#args?),*); let kind = (&result).async_kind(); kind.future(result).await - })); + }); return true; } }) diff --git a/crates/tauri/src/ipc/mod.rs b/crates/tauri/src/ipc/mod.rs index 270833e3a2b5..8e73994fc5cc 100644 --- a/crates/tauri/src/ipc/mod.rs +++ b/crates/tauri/src/ipc/mod.rs @@ -341,7 +341,15 @@ impl InvokeResolver { } /// Reply to the invoke promise with an async task which is already serialized. - pub fn respond_async_serialized( + pub fn respond_async_serialized(self, task: F) + where + F: Future> + Send + 'static, + { + self.respond_async_serialized_dyn(Box::pin(task)) + } + + /// Reply to the invoke promise with an async task which is already serialized. + fn respond_async_serialized_dyn( self, task: Pin> + Send + 'static>>, ) { From 0fb22eb56bd50e1a19fa776dadf66d796b731f54 Mon Sep 17 00:00:00 2001 From: Tony Date: Mon, 19 May 2025 10:57:12 +0800 Subject: [PATCH 5/7] Only do it for dev for now --- crates/tauri/src/ipc/mod.rs | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/crates/tauri/src/ipc/mod.rs b/crates/tauri/src/ipc/mod.rs index 8e73994fc5cc..cdaaa303d007 100644 --- a/crates/tauri/src/ipc/mod.rs +++ b/crates/tauri/src/ipc/mod.rs @@ -345,14 +345,31 @@ impl InvokeResolver { where F: Future> + Send + 'static, { - self.respond_async_serialized_dyn(Box::pin(task)) + // Dynamic dispatch the call in dev for a faster compile time + // TODO: Revisit this and see if we can do this for the release build as well if the performace hit is not a problem + #[cfg(debug_assertions)] + { + self.respond_async_serialized_dyn(Box::pin(task)) + } + #[cfg(not(debug_assertions))] + { + self.respond_async_serialized_inner(task) + } } - /// Reply to the invoke promise with an async task which is already serialized. + /// Dynamic dispatch the [`Self::respond_async_serialized`] call fn respond_async_serialized_dyn( self, task: Pin> + Send + 'static>>, ) { + self.respond_async_serialized_inner(task) + } + + /// Reply to the invoke promise with an async task which is already serialized. + fn respond_async_serialized_inner(self, task: F) + where + F: Future> + Send + 'static, + { crate::async_runtime::spawn(async move { let response = match task.await { Ok(ok) => InvokeResponse::Ok(ok), From d4fe467945b51388cd01dd36e45bd33e93aa89d8 Mon Sep 17 00:00:00 2001 From: Tony Date: Mon, 19 May 2025 10:57:15 +0800 Subject: [PATCH 6/7] Add change file --- .changes/dynamic-dispatch-async-commands.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changes/dynamic-dispatch-async-commands.md diff --git a/.changes/dynamic-dispatch-async-commands.md b/.changes/dynamic-dispatch-async-commands.md new file mode 100644 index 000000000000..3af90a42f116 --- /dev/null +++ b/.changes/dynamic-dispatch-async-commands.md @@ -0,0 +1,5 @@ +--- +tauri: "patch:perf" +--- + +Use dynamic dispatch for async commands in dev, this should speed up the compilation time by quite a bit, and significantly reduces the incremental compilation time From 5a64b09a9d473a02de519526a4a3315a7df4d7a4 Mon Sep 17 00:00:00 2001 From: Tony Date: Mon, 19 May 2025 10:59:34 +0800 Subject: [PATCH 7/7] Tag respond_async_serialized_dyn with debug --- crates/tauri/src/ipc/mod.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/tauri/src/ipc/mod.rs b/crates/tauri/src/ipc/mod.rs index cdaaa303d007..904d6ebba8a2 100644 --- a/crates/tauri/src/ipc/mod.rs +++ b/crates/tauri/src/ipc/mod.rs @@ -6,10 +6,7 @@ //! //! This module includes utilities to send messages to the JS layer of the webview. -use std::{ - pin::Pin, - sync::{Arc, Mutex}, -}; +use std::sync::{Arc, Mutex}; use futures_util::Future; use http::HeaderMap; @@ -358,9 +355,12 @@ impl InvokeResolver { } /// Dynamic dispatch the [`Self::respond_async_serialized`] call + #[cfg(debug_assertions)] fn respond_async_serialized_dyn( self, - task: Pin> + Send + 'static>>, + task: std::pin::Pin< + Box> + Send + 'static>, + >, ) { self.respond_async_serialized_inner(task) }