Use jobserver to limit parallism of cargo-install

Since we execute multiple `cargo-install` concurrently, we must use
jobserver to limit the parallism so that they won't spawn too much
processes/threads to overload the system.

Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com>
This commit is contained in:
Jiahao XU 2022-07-18 21:12:58 +10:00
parent c67c59b3ca
commit fb0a6a5514
No known key found for this signature in database
GPG key ID: 591C0B03040416D6

View file

@ -3,6 +3,7 @@ use std::{
ffi::OsString, ffi::OsString,
mem::take, mem::take,
path::{Path, PathBuf}, path::{Path, PathBuf},
process,
process::{ExitCode, Termination}, process::{ExitCode, Termination},
sync::Arc, sync::Arc,
time::{Duration, Instant}, time::{Duration, Instant},
@ -208,6 +209,9 @@ async fn entry() -> Result<()> {
let crate_names = take(&mut opts.crate_names); let crate_names = take(&mut opts.crate_names);
let opts = Arc::new(opts); let opts = Arc::new(opts);
// Create jobserver client
let jobserver_client = create_jobserver_client()?;
// Initialize reqwest client // Initialize reqwest client
let client = create_reqwest_client(opts.secure, opts.min_tls_version.map(|v| v.into()))?; let client = create_reqwest_client(opts.secure, opts.min_tls_version.map(|v| v.into()))?;
@ -289,6 +293,7 @@ async fn entry() -> Result<()> {
opts.clone(), opts.clone(),
temp_dir_path.clone(), temp_dir_path.clone(),
target.clone(), target.clone(),
jobserver_client.clone(),
)) ))
}) })
.collect() .collect()
@ -300,10 +305,11 @@ async fn entry() -> Result<()> {
let opts = opts.clone(); let opts = opts.clone();
let temp_dir_path = temp_dir_path.clone(); let temp_dir_path = temp_dir_path.clone();
let target = target.clone(); let target = target.clone();
let jobserver_client = jobserver_client.clone();
tokio::spawn(async move { tokio::spawn(async move {
let resolution = await_task(task).await??; let resolution = await_task(task).await??;
install(resolution, opts, temp_dir_path, target).await install(resolution, opts, temp_dir_path, target, jobserver_client).await
}) })
}) })
.collect() .collect()
@ -540,6 +546,7 @@ async fn install(
opts: Arc<Options>, opts: Arc<Options>,
temp_dir: Arc<Path>, temp_dir: Arc<Path>,
target: Arc<str>, target: Arc<str>,
jobserver_client: jobserver::Client,
) -> Result<()> { ) -> Result<()> {
match resolution { match resolution {
Resolution::Fetch { Resolution::Fetch {
@ -557,7 +564,7 @@ async fn install(
} }
Resolution::InstallFromSource { package } => { Resolution::InstallFromSource { package } => {
if !opts.dry_run { if !opts.dry_run {
install_from_source(package, target).await install_from_source(package, target, jobserver_client).await
} else { } else {
info!( info!(
"Dry-run: running `cargo install {} --version {} --target {target}`", "Dry-run: running `cargo install {} --version {} --target {target}`",
@ -667,12 +674,19 @@ async fn install_from_package(
}) })
} }
async fn install_from_source(package: Package<Meta>, target: Arc<str>) -> Result<()> { async fn install_from_source(
package: Package<Meta>,
target: Arc<str>,
jobserver_client: jobserver::Client,
) -> Result<()> {
debug!( debug!(
"Running `cargo install {} --version {} --target {target}`", "Running `cargo install {} --version {} --target {target}`",
package.name, package.version package.name, package.version
); );
let mut child = Command::new("cargo") let mut command = process::Command::new("cargo");
jobserver_client.configure(&mut command);
let mut child = Command::from(command)
.arg("install") .arg("install")
.arg(package.name) .arg(package.name)
.arg("--version") .arg("--version")