From 6a00af30ff11da3a58966e48eb7a67cf358f374b Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sun, 29 Mar 2026 12:01:39 +0000 Subject: [PATCH] perf: parallelize plan operations across realms Implement a `tokio::task::JoinSet` in `src/plan/mod.rs` to process multiple realms concurrently during a plan operation, rather than running sequentially. This drastically improves execution time when the target workspace contains multiple realms. Closes #123 Co-authored-by: ffalcinelli <1167082+ffalcinelli@users.noreply.github.com> --- src/plan/mod.rs | 51 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/src/plan/mod.rs b/src/plan/mod.rs index cd36e16..914abb9 100644 --- a/src/plan/mod.rs +++ b/src/plan/mod.rs @@ -70,29 +70,44 @@ pub async fn run( return Ok(()); } - let mut changed_files = Vec::new(); + let mut set = tokio::task::JoinSet::new(); + for realm_name in realms { let mut realm_client = client.clone(); realm_client.set_target_realm(realm_name.clone()); let realm_dir = workspace_dir.join(&realm_name); - println!( - "\n{} {}", - ACTION, - style(format!("Planning changes for realm: {}", realm_name)) - .cyan() - .bold() - ); - plan_single_realm( - &realm_client, - realm_dir, - changes_only, - interactive, - Arc::clone(&env_vars), - &mut changed_files, - &realm_name, - ) - .await?; + let env_vars = Arc::clone(&env_vars); + + set.spawn(async move { + println!( + "\n{} {}", + ACTION, + style(format!("Planning changes for realm: {}", realm_name)) + .cyan() + .bold() + ); + + let mut changed_files = Vec::new(); + plan_single_realm( + &realm_client, + realm_dir, + changes_only, + interactive, + env_vars, + &mut changed_files, + &realm_name, + ) + .await?; + + Ok::, anyhow::Error>(changed_files) + }); + } + + let mut changed_files = Vec::new(); + while let Some(res) = set.join_next().await { + changed_files.extend(res??); } + changed_files.sort(); let plan_file = workspace_dir.join(".kcdplan"); if changed_files.is_empty() {