Skip to content

Commit c6bbeec

Browse files
committed
build and push profiles asynchronously
build remote builds (remote_build = true) asynchronously to speed up the deployment process. local builds should not be run asynchronously to prevent running into hardware deadlocks
1 parent 9c31476 commit c6bbeec

File tree

2 files changed

+31
-9
lines changed

2 files changed

+31
-9
lines changed

src/cli.rs

+29-7
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ use std::collections::HashMap;
77
use std::io::{stdin, stdout, Write};
88

99
use clap::{ArgMatches, Clap, FromArgMatches};
10+
use futures_util::future::{join_all, try_join_all};
11+
use tokio::try_join;
1012

1113
use crate as deploy;
1214

@@ -545,7 +547,7 @@ async fn run_deploy(
545547

546548
if deploy_data.merged_settings.interactive_sudo.unwrap_or(false) {
547549
warn!("Interactive sudo is enabled! Using a sudo password is less secure than correctly configured SSH keys.\nPlease use keys in production environments.");
548-
550+
549551
if deploy_data.merged_settings.sudo.is_some() {
550552
warn!("Custom sudo commands should be configured to accept password input from stdin when using the 'interactive sudo' option. Deployment may fail if the custom command ignores stdin.");
551553
} else {
@@ -585,13 +587,33 @@ async fn run_deploy(
585587
)
586588
};
587589

588-
for data in data_iter() {
589-
deploy::push::build_profile(data).await?;
590-
}
590+
let (remote_builds, local_builds): (Vec<_>, Vec<_>) = data_iter().partition(|data| {
591+
data.deploy_data.merged_settings.remote_build.unwrap_or_default()
592+
});
593+
594+
// await both the remote builds and the local builds to speed up deployment times
595+
try_join!(
596+
// remote builds can be run asynchronously since they do not affect the local machine
597+
try_join_all(remote_builds.into_iter().map(|data| async {
598+
let data = data;
599+
deploy::push::build_profile(&data).await
600+
})),
601+
async {
602+
// run local builds synchronously to prevent hardware deadlocks
603+
for data in &local_builds {
604+
deploy::push::build_profile(data).await?;
605+
}
606+
607+
// push all profiles asynchronously
608+
join_all(local_builds.into_iter().map(|data| async {
609+
let data = data;
610+
deploy::push::push_profile(&data).await
611+
})).await;
612+
613+
Ok(())
614+
}
615+
)?;
591616

592-
for data in data_iter() {
593-
deploy::push::push_profile(data).await?;
594-
}
595617

596618
let mut succeeded: Vec<(&deploy::DeployData, &deploy::DeployDefs)> = vec![];
597619

src/push.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ pub async fn build_profile_remotely(data: &PushProfileData<'_>, derivation_name:
210210
Ok(())
211211
}
212212

213-
pub async fn build_profile(data: PushProfileData<'_>) -> Result<(), PushProfileError> {
213+
pub async fn build_profile(data: &PushProfileData<'_>) -> Result<(), PushProfileError> {
214214
debug!(
215215
"Finding the deriver of store path for {}",
216216
&data.deploy_data.profile.profile_settings.path
@@ -283,7 +283,7 @@ pub async fn build_profile(data: PushProfileData<'_>) -> Result<(), PushProfileE
283283
Ok(())
284284
}
285285

286-
pub async fn push_profile(data: PushProfileData<'_>) -> Result<(), PushProfileError> {
286+
pub async fn push_profile(data: &PushProfileData<'_>) -> Result<(), PushProfileError> {
287287
let ssh_opts_str = data
288288
.deploy_data
289289
.merged_settings

0 commit comments

Comments
 (0)