From 640db2d079b1209254b830d22c00bd5597edad75 Mon Sep 17 00:00:00 2001 From: Wyatt Verchere Date: Tue, 18 Apr 2023 14:43:30 -0700 Subject: [PATCH] fixes stack overflow :) (#88) * fixes stack overflow :) * removed unnecessary comment --- theseus/src/event/emit.rs | 81 ++++++++++++++++----------------------- theseus/src/state/mod.rs | 2 +- theseus/src/state/tags.rs | 2 +- 3 files changed, 34 insertions(+), 51 deletions(-) diff --git a/theseus/src/event/emit.rs b/theseus/src/event/emit.rs index 22fb69f10..eea03c541 100644 --- a/theseus/src/event/emit.rs +++ b/theseus/src/event/emit.rs @@ -194,70 +194,53 @@ pub async fn emit_profile( // loading_join!(loading_bar, 0.1; task1, task2, task3) // This will await on each of the tasks, and as each completes, it will emit a loading event for 0.033, 0.066, 0.099, etc // This should function as a drop-in replacement for tokio::try_join_all! in most cases- except the function *itself* calls ? rather than needing it. +#[macro_export] +macro_rules! count { + () => (0usize); + ( $x:tt $($xs:tt)* ) => (1usize + $crate::count!($($xs)*)); +} #[cfg(feature = "tauri")] #[macro_export] macro_rules! loading_join { - ($key:expr, $total:expr, $message:expr; $($future:expr $(,)?)+) => {{ - let mut num_futures = 0; - $( - { - let _ = &$future; // useless to allow matching to $future - num_futures += 1; - } - )* + ($key:expr, $total:expr, $message:expr; $($task:expr $(,)?)+) => { + { + let key = $key; + let message : Option<&str> = $message; + + let num_futures = $crate::count!($($task)*); let increment = $total / num_futures as f64; - // Create tokio::pinned values - $( - paste::paste! { - tokio::pin! { - let [] = $future; - } - } - )* - $( - paste::paste! { - let mut [] = None; - } - )* - // Resolve each future and call respective loading as each resolves in any order - for _ in 0..num_futures { - paste::paste! { - tokio::select! { - $( - v = &mut [], if ![].is_some() => { - if let Some(key) = $key { - $crate::event::emit::emit_loading(key, increment, $message).await?; - } - [] = Some(v); - }, - )* - else => break, + paste::paste! { + $( let [ ] = { + { + let key = key.clone(); + let message = message.clone(); + async move { + let res = $task.await; + if let Some(key) = key { + $crate::event::emit::emit_loading(key, increment, message).await?; + } + res + } } - } + };)+ } - // Extract values out of option, then out of error, returning if any errors happened - $( - paste::paste! { - let [] = [].take().unwrap()?; // unwrap here acceptable as numbers of futures and resolved values is guaranteed to be the same - } - )* - - paste::paste!{ - ($( - [], // unwrap here acceptable as numbers of futures and resolved values is guaranteed to be the same - )+) + paste::paste! { + tokio::try_join! ( + $( [ ] ),+ + ) } - }}; + } + }; + } - #[cfg(not(feature = "tauri"))] #[macro_export] macro_rules! loading_join { ($start:expr, $end:expr, $message:expr; $($future:expr $(,)?)+) => {{ - tokio::try_join!($($future),+)? + tokio::try_join!($($future),+) }}; } diff --git a/theseus/src/state/mod.rs b/theseus/src/state/mod.rs index 31d5fe5af..82ce0f1bf 100644 --- a/theseus/src/state/mod.rs +++ b/theseus/src/state/mod.rs @@ -105,7 +105,7 @@ impl State { let (metadata, profiles) = loading_join! { Some(&loading_bar), 20.0, Some("Initializing metadata and profiles..."); metadata_fut, profiles_fut - }; + }?; emit_loading(&loading_bar, 10.0, None).await?; let users = Users::init(&database)?; diff --git a/theseus/src/state/tags.rs b/theseus/src/state/tags.rs index 346e0ff2c..ec6e31e31 100644 --- a/theseus/src/state/tags.rs +++ b/theseus/src/state/tags.rs @@ -208,7 +208,7 @@ impl Tags { licenses_fut, donation_platforms_fut, report_types_fut - ); + )?; // Store the tags in the database self.0.categories.insert(