mirror of
https://github.com/cargo-bins/cargo-binstall.git
synced 2025-04-21 21:18:42 +00:00
Optimize GhCrateMeta::find
: Cache url resolution result (#810)
So that we don't have to create multiple HEAD/GET http request to get the final, redirected url. Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com>
This commit is contained in:
parent
a8b9ae6fda
commit
2e118b3044
3 changed files with 75 additions and 50 deletions
|
@ -3,6 +3,8 @@ use std::{path::Path, sync::Arc};
|
|||
use compact_str::CompactString;
|
||||
pub use gh_crate_meta::*;
|
||||
pub use quickinstall::*;
|
||||
use tokio::sync::OnceCell;
|
||||
use url::Url;
|
||||
|
||||
use crate::{
|
||||
errors::BinstallError,
|
||||
|
@ -60,9 +62,37 @@ pub trait Fetcher: Send + Sync {
|
|||
/// Data required to fetch a package
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Data {
|
||||
pub name: CompactString,
|
||||
pub version: CompactString,
|
||||
pub repo: Option<String>,
|
||||
name: CompactString,
|
||||
version: CompactString,
|
||||
repo: Option<String>,
|
||||
repo_final_url: OnceCell<Option<Url>>,
|
||||
}
|
||||
|
||||
impl Data {
|
||||
pub fn new(name: CompactString, version: CompactString, repo: Option<String>) -> Self {
|
||||
Self {
|
||||
name,
|
||||
version,
|
||||
repo,
|
||||
repo_final_url: OnceCell::new(),
|
||||
}
|
||||
}
|
||||
|
||||
async fn resolve_final_repo_url(&self, client: &Client) -> Result<&Option<Url>, BinstallError> {
|
||||
self.repo_final_url
|
||||
.get_or_try_init(move || {
|
||||
Box::pin(async move {
|
||||
if let Some(repo) = self.repo.as_deref() {
|
||||
Ok(Some(
|
||||
client.get_redirected_final_url(Url::parse(repo)?).await?,
|
||||
))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
})
|
||||
})
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
/// Target specific data required to fetch a package
|
||||
|
|
|
@ -92,11 +92,7 @@ impl super::Fetcher for GhCrateMeta {
|
|||
|
||||
fn find(self: Arc<Self>) -> AutoAbortJoinHandle<Result<bool, BinstallError>> {
|
||||
AutoAbortJoinHandle::spawn(async move {
|
||||
let repo = if let Some(repo) = self.data.repo.as_deref() {
|
||||
Some(Box::pin(self.client.get_redirected_final_url(Url::parse(repo)?)).await?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let repo = self.data.resolve_final_repo_url(&self.client).await?;
|
||||
|
||||
let mut pkg_fmt = self.target_data.meta.pkg_fmt;
|
||||
|
||||
|
@ -156,8 +152,7 @@ impl super::Fetcher for GhCrateMeta {
|
|||
};
|
||||
|
||||
// Convert Option<Url> to Option<String> to reduce size of future.
|
||||
let repo = repo.map(String::from);
|
||||
let repo = repo.as_deref().map(|u| u.trim_end_matches('/'));
|
||||
let repo = repo.as_ref().map(|u| u.as_str().trim_end_matches('/'));
|
||||
|
||||
// Use reference to self to fix error of closure
|
||||
// launch_baseline_find_tasks which moves `this`
|
||||
|
@ -337,11 +332,11 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn defaults() {
|
||||
let data = Data {
|
||||
name: "cargo-binstall".to_compact_string(),
|
||||
version: "1.2.3".to_compact_string(),
|
||||
repo: Some("https://github.com/ryankurte/cargo-binstall".to_string()),
|
||||
};
|
||||
let data = Data::new(
|
||||
"cargo-binstall".to_compact_string(),
|
||||
"1.2.3".to_compact_string(),
|
||||
Some("https://github.com/ryankurte/cargo-binstall".to_string()),
|
||||
);
|
||||
|
||||
let ctx = Context::from_data(&data, "x86_64-unknown-linux-gnu", ".tgz");
|
||||
assert_eq!(
|
||||
|
@ -354,11 +349,11 @@ mod test {
|
|||
#[should_panic]
|
||||
fn no_repo() {
|
||||
let meta = PkgMeta::default();
|
||||
let data = Data {
|
||||
name: "cargo-binstall".to_compact_string(),
|
||||
version: "1.2.3".to_compact_string(),
|
||||
repo: None,
|
||||
};
|
||||
let data = Data::new(
|
||||
"cargo-binstall".to_compact_string(),
|
||||
"1.2.3".to_compact_string(),
|
||||
None,
|
||||
);
|
||||
|
||||
let ctx = Context::from_data(&data, "x86_64-unknown-linux-gnu", ".tgz");
|
||||
ctx.render_url(meta.pkg_url.as_deref().unwrap()).unwrap();
|
||||
|
@ -371,11 +366,11 @@ mod test {
|
|||
..Default::default()
|
||||
};
|
||||
|
||||
let data = Data {
|
||||
name: "cargo-binstall".to_compact_string(),
|
||||
version: "1.2.3".to_compact_string(),
|
||||
repo: None,
|
||||
};
|
||||
let data = Data::new(
|
||||
"cargo-binstall".to_compact_string(),
|
||||
"1.2.3".to_compact_string(),
|
||||
None,
|
||||
);
|
||||
|
||||
let ctx = Context::from_data(&data, "x86_64-unknown-linux-gnu", ".tgz");
|
||||
assert_eq!(
|
||||
|
@ -393,11 +388,11 @@ mod test {
|
|||
..Default::default()
|
||||
};
|
||||
|
||||
let data = Data {
|
||||
name: "radio-sx128x".to_compact_string(),
|
||||
version: "0.14.1-alpha.5".to_compact_string(),
|
||||
repo: Some("https://github.com/rust-iot/rust-radio-sx128x".to_string()),
|
||||
};
|
||||
let data = Data::new(
|
||||
"radio-sx128x".to_compact_string(),
|
||||
"0.14.1-alpha.5".to_compact_string(),
|
||||
Some("https://github.com/rust-iot/rust-radio-sx128x".to_string()),
|
||||
);
|
||||
|
||||
let ctx = Context::from_data(&data, "x86_64-unknown-linux-gnu", ".tgz");
|
||||
assert_eq!(
|
||||
|
@ -413,11 +408,11 @@ mod test {
|
|||
..Default::default()
|
||||
};
|
||||
|
||||
let data = Data {
|
||||
name: "radio-sx128x".to_compact_string(),
|
||||
version: "0.14.1-alpha.5".to_compact_string(),
|
||||
repo: Some("https://github.com/rust-iot/rust-radio-sx128x".to_string()),
|
||||
};
|
||||
let data = Data::new(
|
||||
"radio-sx128x".to_compact_string(),
|
||||
"0.14.1-alpha.5".to_compact_string(),
|
||||
Some("https://github.com/rust-iot/rust-radio-sx128x".to_string()),
|
||||
);
|
||||
|
||||
let ctx = Context::from_data(&data, "x86_64-unknown-linux-gnu", ".tgz");
|
||||
assert_eq!(
|
||||
|
@ -437,11 +432,11 @@ mod test {
|
|||
..Default::default()
|
||||
};
|
||||
|
||||
let data = Data {
|
||||
name: "cargo-watch".to_compact_string(),
|
||||
version: "9.0.0".to_compact_string(),
|
||||
repo: Some("https://github.com/watchexec/cargo-watch".to_string()),
|
||||
};
|
||||
let data = Data::new(
|
||||
"cargo-watch".to_compact_string(),
|
||||
"9.0.0".to_compact_string(),
|
||||
Some("https://github.com/watchexec/cargo-watch".to_string()),
|
||||
);
|
||||
|
||||
let ctx = Context::from_data(&data, "aarch64-apple-darwin", ".txz");
|
||||
assert_eq!(
|
||||
|
@ -458,11 +453,11 @@ mod test {
|
|||
..Default::default()
|
||||
};
|
||||
|
||||
let data = Data {
|
||||
name: "cargo-watch".to_compact_string(),
|
||||
version: "9.0.0".to_compact_string(),
|
||||
repo: Some("https://github.com/watchexec/cargo-watch".to_string()),
|
||||
};
|
||||
let data = Data::new(
|
||||
"cargo-watch".to_compact_string(),
|
||||
"9.0.0".to_compact_string(),
|
||||
Some("https://github.com/watchexec/cargo-watch".to_string()),
|
||||
);
|
||||
|
||||
let ctx = Context::from_data(&data, "aarch64-pc-windows-msvc", ".bin");
|
||||
assert_eq!(
|
||||
|
|
|
@ -84,11 +84,11 @@ async fn resolve_inner(
|
|||
let mut handles: Vec<(Arc<dyn Fetcher>, _)> =
|
||||
Vec::with_capacity(desired_targets.len() * resolvers.len());
|
||||
|
||||
let data = Arc::new(Data {
|
||||
name: package_info.name.clone(),
|
||||
version: package_info.version_str.clone(),
|
||||
repo: package_info.repo.clone(),
|
||||
});
|
||||
let data = Arc::new(Data::new(
|
||||
package_info.name.clone(),
|
||||
package_info.version_str.clone(),
|
||||
package_info.repo.clone(),
|
||||
));
|
||||
|
||||
handles.extend(
|
||||
desired_targets
|
||||
|
|
Loading…
Add table
Reference in a new issue