Skip to content

Commit

Permalink
build and push profiles asynchronously
Browse files Browse the repository at this point in the history
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
  • Loading branch information
PhilTaken committed Jun 10, 2024
1 parent 9c31476 commit c6bbeec
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 9 deletions.
36 changes: 29 additions & 7 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ use std::collections::HashMap;
use std::io::{stdin, stdout, Write};

use clap::{ArgMatches, Clap, FromArgMatches};
use futures_util::future::{join_all, try_join_all};
use tokio::try_join;

use crate as deploy;

Expand Down Expand Up @@ -545,7 +547,7 @@ async fn run_deploy(

if deploy_data.merged_settings.interactive_sudo.unwrap_or(false) {
warn!("Interactive sudo is enabled! Using a sudo password is less secure than correctly configured SSH keys.\nPlease use keys in production environments.");

if deploy_data.merged_settings.sudo.is_some() {
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.");
} else {
Expand Down Expand Up @@ -585,13 +587,33 @@ async fn run_deploy(
)
};

for data in data_iter() {
deploy::push::build_profile(data).await?;
}
let (remote_builds, local_builds): (Vec<_>, Vec<_>) = data_iter().partition(|data| {
data.deploy_data.merged_settings.remote_build.unwrap_or_default()
});

// await both the remote builds and the local builds to speed up deployment times
try_join!(
// remote builds can be run asynchronously since they do not affect the local machine
try_join_all(remote_builds.into_iter().map(|data| async {
let data = data;
deploy::push::build_profile(&data).await
})),
async {
// run local builds synchronously to prevent hardware deadlocks
for data in &local_builds {
deploy::push::build_profile(data).await?;
}

// push all profiles asynchronously
join_all(local_builds.into_iter().map(|data| async {
let data = data;
deploy::push::push_profile(&data).await
})).await;

Ok(())
}
)?;

for data in data_iter() {
deploy::push::push_profile(data).await?;
}

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

Expand Down
4 changes: 2 additions & 2 deletions src/push.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ pub async fn build_profile_remotely(data: &PushProfileData<'_>, derivation_name:
Ok(())
}

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

pub async fn push_profile(data: PushProfileData<'_>) -> Result<(), PushProfileError> {
pub async fn push_profile(data: &PushProfileData<'_>) -> Result<(), PushProfileError> {
let ssh_opts_str = data
.deploy_data
.merged_settings
Expand Down

0 comments on commit c6bbeec

Please sign in to comment.