mirror of
https://github.com/cargo-bins/cargo-binstall.git
synced 2025-05-05 11:40:04 +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
crates/binstalk/src
|
@ -3,6 +3,8 @@ use std::{path::Path, sync::Arc};
|
||||||
use compact_str::CompactString;
|
use compact_str::CompactString;
|
||||||
pub use gh_crate_meta::*;
|
pub use gh_crate_meta::*;
|
||||||
pub use quickinstall::*;
|
pub use quickinstall::*;
|
||||||
|
use tokio::sync::OnceCell;
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
errors::BinstallError,
|
errors::BinstallError,
|
||||||
|
@ -60,9 +62,37 @@ pub trait Fetcher: Send + Sync {
|
||||||
/// Data required to fetch a package
|
/// Data required to fetch a package
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Data {
|
pub struct Data {
|
||||||
pub name: CompactString,
|
name: CompactString,
|
||||||
pub version: CompactString,
|
version: CompactString,
|
||||||
pub repo: Option<String>,
|
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
|
/// 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>> {
|
fn find(self: Arc<Self>) -> AutoAbortJoinHandle<Result<bool, BinstallError>> {
|
||||||
AutoAbortJoinHandle::spawn(async move {
|
AutoAbortJoinHandle::spawn(async move {
|
||||||
let repo = if let Some(repo) = self.data.repo.as_deref() {
|
let repo = self.data.resolve_final_repo_url(&self.client).await?;
|
||||||
Some(Box::pin(self.client.get_redirected_final_url(Url::parse(repo)?)).await?)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut pkg_fmt = self.target_data.meta.pkg_fmt;
|
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.
|
// Convert Option<Url> to Option<String> to reduce size of future.
|
||||||
let repo = repo.map(String::from);
|
let repo = repo.as_ref().map(|u| u.as_str().trim_end_matches('/'));
|
||||||
let repo = repo.as_deref().map(|u| u.trim_end_matches('/'));
|
|
||||||
|
|
||||||
// Use reference to self to fix error of closure
|
// Use reference to self to fix error of closure
|
||||||
// launch_baseline_find_tasks which moves `this`
|
// launch_baseline_find_tasks which moves `this`
|
||||||
|
@ -337,11 +332,11 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn defaults() {
|
fn defaults() {
|
||||||
let data = Data {
|
let data = Data::new(
|
||||||
name: "cargo-binstall".to_compact_string(),
|
"cargo-binstall".to_compact_string(),
|
||||||
version: "1.2.3".to_compact_string(),
|
"1.2.3".to_compact_string(),
|
||||||
repo: Some("https://github.com/ryankurte/cargo-binstall".to_string()),
|
Some("https://github.com/ryankurte/cargo-binstall".to_string()),
|
||||||
};
|
);
|
||||||
|
|
||||||
let ctx = Context::from_data(&data, "x86_64-unknown-linux-gnu", ".tgz");
|
let ctx = Context::from_data(&data, "x86_64-unknown-linux-gnu", ".tgz");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -354,11 +349,11 @@ mod test {
|
||||||
#[should_panic]
|
#[should_panic]
|
||||||
fn no_repo() {
|
fn no_repo() {
|
||||||
let meta = PkgMeta::default();
|
let meta = PkgMeta::default();
|
||||||
let data = Data {
|
let data = Data::new(
|
||||||
name: "cargo-binstall".to_compact_string(),
|
"cargo-binstall".to_compact_string(),
|
||||||
version: "1.2.3".to_compact_string(),
|
"1.2.3".to_compact_string(),
|
||||||
repo: None,
|
None,
|
||||||
};
|
);
|
||||||
|
|
||||||
let ctx = Context::from_data(&data, "x86_64-unknown-linux-gnu", ".tgz");
|
let ctx = Context::from_data(&data, "x86_64-unknown-linux-gnu", ".tgz");
|
||||||
ctx.render_url(meta.pkg_url.as_deref().unwrap()).unwrap();
|
ctx.render_url(meta.pkg_url.as_deref().unwrap()).unwrap();
|
||||||
|
@ -371,11 +366,11 @@ mod test {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let data = Data {
|
let data = Data::new(
|
||||||
name: "cargo-binstall".to_compact_string(),
|
"cargo-binstall".to_compact_string(),
|
||||||
version: "1.2.3".to_compact_string(),
|
"1.2.3".to_compact_string(),
|
||||||
repo: None,
|
None,
|
||||||
};
|
);
|
||||||
|
|
||||||
let ctx = Context::from_data(&data, "x86_64-unknown-linux-gnu", ".tgz");
|
let ctx = Context::from_data(&data, "x86_64-unknown-linux-gnu", ".tgz");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -393,11 +388,11 @@ mod test {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let data = Data {
|
let data = Data::new(
|
||||||
name: "radio-sx128x".to_compact_string(),
|
"radio-sx128x".to_compact_string(),
|
||||||
version: "0.14.1-alpha.5".to_compact_string(),
|
"0.14.1-alpha.5".to_compact_string(),
|
||||||
repo: Some("https://github.com/rust-iot/rust-radio-sx128x".to_string()),
|
Some("https://github.com/rust-iot/rust-radio-sx128x".to_string()),
|
||||||
};
|
);
|
||||||
|
|
||||||
let ctx = Context::from_data(&data, "x86_64-unknown-linux-gnu", ".tgz");
|
let ctx = Context::from_data(&data, "x86_64-unknown-linux-gnu", ".tgz");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -413,11 +408,11 @@ mod test {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let data = Data {
|
let data = Data::new(
|
||||||
name: "radio-sx128x".to_compact_string(),
|
"radio-sx128x".to_compact_string(),
|
||||||
version: "0.14.1-alpha.5".to_compact_string(),
|
"0.14.1-alpha.5".to_compact_string(),
|
||||||
repo: Some("https://github.com/rust-iot/rust-radio-sx128x".to_string()),
|
Some("https://github.com/rust-iot/rust-radio-sx128x".to_string()),
|
||||||
};
|
);
|
||||||
|
|
||||||
let ctx = Context::from_data(&data, "x86_64-unknown-linux-gnu", ".tgz");
|
let ctx = Context::from_data(&data, "x86_64-unknown-linux-gnu", ".tgz");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -437,11 +432,11 @@ mod test {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let data = Data {
|
let data = Data::new(
|
||||||
name: "cargo-watch".to_compact_string(),
|
"cargo-watch".to_compact_string(),
|
||||||
version: "9.0.0".to_compact_string(),
|
"9.0.0".to_compact_string(),
|
||||||
repo: Some("https://github.com/watchexec/cargo-watch".to_string()),
|
Some("https://github.com/watchexec/cargo-watch".to_string()),
|
||||||
};
|
);
|
||||||
|
|
||||||
let ctx = Context::from_data(&data, "aarch64-apple-darwin", ".txz");
|
let ctx = Context::from_data(&data, "aarch64-apple-darwin", ".txz");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -458,11 +453,11 @@ mod test {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let data = Data {
|
let data = Data::new(
|
||||||
name: "cargo-watch".to_compact_string(),
|
"cargo-watch".to_compact_string(),
|
||||||
version: "9.0.0".to_compact_string(),
|
"9.0.0".to_compact_string(),
|
||||||
repo: Some("https://github.com/watchexec/cargo-watch".to_string()),
|
Some("https://github.com/watchexec/cargo-watch".to_string()),
|
||||||
};
|
);
|
||||||
|
|
||||||
let ctx = Context::from_data(&data, "aarch64-pc-windows-msvc", ".bin");
|
let ctx = Context::from_data(&data, "aarch64-pc-windows-msvc", ".bin");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|
|
@ -84,11 +84,11 @@ async fn resolve_inner(
|
||||||
let mut handles: Vec<(Arc<dyn Fetcher>, _)> =
|
let mut handles: Vec<(Arc<dyn Fetcher>, _)> =
|
||||||
Vec::with_capacity(desired_targets.len() * resolvers.len());
|
Vec::with_capacity(desired_targets.len() * resolvers.len());
|
||||||
|
|
||||||
let data = Arc::new(Data {
|
let data = Arc::new(Data::new(
|
||||||
name: package_info.name.clone(),
|
package_info.name.clone(),
|
||||||
version: package_info.version_str.clone(),
|
package_info.version_str.clone(),
|
||||||
repo: package_info.repo.clone(),
|
package_info.repo.clone(),
|
||||||
});
|
));
|
||||||
|
|
||||||
handles.extend(
|
handles.extend(
|
||||||
desired_targets
|
desired_targets
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue