mirror of
https://github.com/cargo-bins/cargo-binstall.git
synced 2025-04-20 12:38:43 +00:00
Optimize Fetcher::find
and fix quickinstall reporting (#579)
* Optimize `Fetcher::find`: Make it non-async to avoid boxing and return `AutoAbortJoinHandle<...>` instead. Since spawning a new task in tokio box the future anyway, boxing the returned future again in `Fetcher::find` merely adds unnecessary overheads. * Optimize `QuickInstall::report`: Make it async fn instead of ret `JoinHandle` This provides several benefits: - On debug build, no task will be spawned - The calls to `self.stats_url()` can be evaluated in parallel. - The task now returns `()` so that the task spawned is smaller. * Fix `QuickInstall::find`: `warn!` if quickinstall report fails Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com>
This commit is contained in:
parent
ff737730f4
commit
ab3e47c42b
4 changed files with 93 additions and 84 deletions
|
@ -6,7 +6,7 @@ pub use quickinstall::*;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
errors::BinstallError,
|
errors::BinstallError,
|
||||||
helpers::remote::Client,
|
helpers::{remote::Client, tasks::AutoAbortJoinHandle},
|
||||||
manifests::cargo_toml_binstall::{PkgFmt, PkgMeta},
|
manifests::cargo_toml_binstall::{PkgFmt, PkgMeta},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ pub trait Fetcher: Send + Sync {
|
||||||
///
|
///
|
||||||
/// Must return `true` if a package is available, `false` if none is, and reserve errors to
|
/// Must return `true` if a package is available, `false` if none is, and reserve errors to
|
||||||
/// fatal conditions only.
|
/// fatal conditions only.
|
||||||
async fn find(&self) -> Result<bool, BinstallError>;
|
fn find(self: Arc<Self>) -> AutoAbortJoinHandle<Result<bool, BinstallError>>;
|
||||||
|
|
||||||
/// Return the package format
|
/// Return the package format
|
||||||
fn pkg_fmt(&self) -> PkgFmt;
|
fn pkg_fmt(&self) -> PkgFmt;
|
||||||
|
|
|
@ -16,6 +16,7 @@ use crate::{
|
||||||
download::Download,
|
download::Download,
|
||||||
remote::{Client, Method},
|
remote::{Client, Method},
|
||||||
signal::wait_on_cancellation_signal,
|
signal::wait_on_cancellation_signal,
|
||||||
|
tasks::AutoAbortJoinHandle,
|
||||||
},
|
},
|
||||||
manifests::cargo_toml_binstall::{PkgFmt, PkgMeta},
|
manifests::cargo_toml_binstall::{PkgFmt, PkgMeta},
|
||||||
};
|
};
|
||||||
|
@ -83,7 +84,8 @@ impl super::Fetcher for GhCrateMeta {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn find(&self) -> Result<bool, BinstallError> {
|
fn find(self: Arc<Self>) -> AutoAbortJoinHandle<Result<bool, BinstallError>> {
|
||||||
|
AutoAbortJoinHandle::spawn(async move {
|
||||||
let repo = if let Some(repo) = self.data.repo.as_deref() {
|
let repo = if let Some(repo) = self.data.repo.as_deref() {
|
||||||
Some(
|
Some(
|
||||||
self.client
|
self.client
|
||||||
|
@ -128,16 +130,20 @@ impl super::Fetcher for GhCrateMeta {
|
||||||
let repo = repo.map(String::from);
|
let repo = repo.map(String::from);
|
||||||
let repo = repo.as_deref().map(|u| u.trim_end_matches('/'));
|
let repo = repo.as_deref().map(|u| u.trim_end_matches('/'));
|
||||||
|
|
||||||
|
// Use reference to self to fix error of closure
|
||||||
|
// launch_baseline_find_tasks which moves `this`
|
||||||
|
let this = &self;
|
||||||
|
|
||||||
let launch_baseline_find_tasks = |pkg_fmt| {
|
let launch_baseline_find_tasks = |pkg_fmt| {
|
||||||
match &pkg_urls {
|
match &pkg_urls {
|
||||||
Either::Left(pkg_url) => Either::Left(iter::once(*pkg_url)),
|
Either::Left(pkg_url) => Either::Left(iter::once(*pkg_url)),
|
||||||
Either::Right(pkg_urls) => Either::Right(pkg_urls.iter().map(Deref::deref)),
|
Either::Right(pkg_urls) => Either::Right(pkg_urls.iter().map(Deref::deref)),
|
||||||
}
|
}
|
||||||
.flat_map(move |pkg_url| self.launch_baseline_find_tasks(pkg_fmt, pkg_url, repo))
|
.flat_map(move |pkg_url| this.launch_baseline_find_tasks(pkg_fmt, pkg_url, repo))
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut handles: FuturesUnordered<_> = if let Some(pkg_fmt) = self.target_data.meta.pkg_fmt
|
let mut handles: FuturesUnordered<_> =
|
||||||
{
|
if let Some(pkg_fmt) = self.target_data.meta.pkg_fmt {
|
||||||
launch_baseline_find_tasks(pkg_fmt).collect()
|
launch_baseline_find_tasks(pkg_fmt).collect()
|
||||||
} else {
|
} else {
|
||||||
PkgFmt::iter()
|
PkgFmt::iter()
|
||||||
|
@ -154,6 +160,7 @@ impl super::Fetcher for GhCrateMeta {
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(false)
|
Ok(false)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn fetch_and_extract(&self, dst: &Path) -> Result<(), BinstallError> {
|
async fn fetch_and_extract(&self, dst: &Path) -> Result<(), BinstallError> {
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
use std::{path::Path, sync::Arc};
|
use std::{path::Path, sync::Arc};
|
||||||
|
|
||||||
use compact_str::CompactString;
|
use compact_str::CompactString;
|
||||||
use tokio::task::JoinHandle;
|
use tracing::{debug, warn};
|
||||||
use tracing::debug;
|
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -11,6 +10,7 @@ use crate::{
|
||||||
download::Download,
|
download::Download,
|
||||||
remote::{Client, Method},
|
remote::{Client, Method},
|
||||||
signal::wait_on_cancellation_signal,
|
signal::wait_on_cancellation_signal,
|
||||||
|
tasks::AutoAbortJoinHandle,
|
||||||
},
|
},
|
||||||
manifests::cargo_toml_binstall::{PkgFmt, PkgMeta},
|
manifests::cargo_toml_binstall::{PkgFmt, PkgMeta},
|
||||||
};
|
};
|
||||||
|
@ -43,14 +43,29 @@ impl super::Fetcher for QuickInstall {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn find(&self) -> Result<bool, BinstallError> {
|
fn find(self: Arc<Self>) -> AutoAbortJoinHandle<Result<bool, BinstallError>> {
|
||||||
|
AutoAbortJoinHandle::spawn(async move {
|
||||||
|
if cfg!(debug_assertions) {
|
||||||
|
debug!("Not sending quickinstall report in debug mode");
|
||||||
|
} else {
|
||||||
|
let this = self.clone();
|
||||||
|
tokio::spawn(async move {
|
||||||
|
if let Err(err) = this.report().await {
|
||||||
|
warn!(
|
||||||
|
"Failed to send quickinstall report for package {}: {err}",
|
||||||
|
this.package
|
||||||
|
)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
let url = self.package_url();
|
let url = self.package_url();
|
||||||
self.report();
|
|
||||||
debug!("Checking for package at: '{url}'");
|
debug!("Checking for package at: '{url}'");
|
||||||
Ok(self
|
Ok(self
|
||||||
.client
|
.client
|
||||||
.remote_exists(Url::parse(&url)?, Method::HEAD)
|
.remote_exists(Url::parse(&url)?, Method::HEAD)
|
||||||
.await?)
|
.await?)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn fetch_and_extract(&self, dst: &Path) -> Result<(), BinstallError> {
|
async fn fetch_and_extract(&self, dst: &Path) -> Result<(), BinstallError> {
|
||||||
|
@ -110,22 +125,12 @@ impl QuickInstall {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn report(&self) -> JoinHandle<Result<(), BinstallError>> {
|
pub async fn report(&self) -> Result<(), BinstallError> {
|
||||||
let stats_url = self.stats_url();
|
let url = Url::parse(&self.stats_url())?;
|
||||||
let client = self.client.clone();
|
|
||||||
|
|
||||||
tokio::spawn(async move {
|
|
||||||
if cfg!(debug_assertions) {
|
|
||||||
debug!("Not sending quickinstall report in debug mode");
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
|
|
||||||
let url = Url::parse(&stats_url)?;
|
|
||||||
debug!("Sending installation report to quickinstall ({url})");
|
debug!("Sending installation report to quickinstall ({url})");
|
||||||
|
|
||||||
client.remote_exists(url, Method::HEAD).await?;
|
self.client.remote_exists(url, Method::HEAD).await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ use crate::{
|
||||||
drivers::fetch_crate_cratesio,
|
drivers::fetch_crate_cratesio,
|
||||||
errors::BinstallError,
|
errors::BinstallError,
|
||||||
fetchers::{Data, Fetcher, TargetData},
|
fetchers::{Data, Fetcher, TargetData},
|
||||||
helpers::{remote::Client, tasks::AutoAbortJoinHandle},
|
helpers::remote::Client,
|
||||||
manifests::cargo_toml_binstall::{Meta, PkgMeta, PkgOverride},
|
manifests::cargo_toml_binstall::{Meta, PkgMeta, PkgOverride},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -162,10 +162,7 @@ async fn resolve_inner(
|
||||||
.cartesian_product(resolvers)
|
.cartesian_product(resolvers)
|
||||||
.map(|(target_data, f)| {
|
.map(|(target_data, f)| {
|
||||||
let fetcher = f(opts.client.clone(), data.clone(), target_data);
|
let fetcher = f(opts.client.clone(), data.clone(), target_data);
|
||||||
(
|
(fetcher.clone(), fetcher.find())
|
||||||
fetcher.clone(),
|
|
||||||
AutoAbortJoinHandle::spawn(async move { fetcher.find().await }),
|
|
||||||
)
|
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue