Optimize GhCrateMeta::find: use FuturesUnordered (#321)

* Optimize `GhCrateMeta::find` using `FuturesUnordered`
* Optimize `MultiFetcher`: Impl `with_capacity` use it in `resolve_inner` to avoid over-reservation
* Enable feature "std" of dep futures-util

Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com>
This commit is contained in:
Jiahao XU 2022-08-27 19:56:43 +10:00 committed by GitHub
parent 4def4d08fd
commit 16b16c482c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 11 additions and 7 deletions

View file

@ -20,7 +20,7 @@ crates_io_api = { version = "0.8.0", default-features = false }
detect-targets = { version = "0.1.0", path = "../detect-targets" }
flate2 = { version = "1.0.24", default-features = false }
flock = { version = "0.1.0", path = "../flock" }
futures-util = { version = "0.3.23", default-features = false }
futures-util = { version = "0.3.23", default-features = false, features = ["std"] }
home = "0.5.3"
itertools = "0.10.3"
jobserver = "0.1.24"

View file

@ -63,10 +63,13 @@ pub struct Data {
type FetcherJoinHandle = AutoAbortJoinHandle<Result<bool, BinstallError>>;
#[derive(Default)]
pub struct MultiFetcher(Vec<(Arc<dyn Fetcher>, FetcherJoinHandle)>);
impl MultiFetcher {
pub fn with_capacity(n: usize) -> Self {
Self(Vec::with_capacity(n))
}
pub fn add(&mut self, fetcher: Arc<dyn Fetcher>) {
self.0.push((
fetcher.clone(),

View file

@ -1,6 +1,7 @@
use std::{borrow::Cow, path::Path, sync::Arc};
use compact_str::{CompactString, ToCompactString};
use futures_util::stream::{FuturesUnordered, StreamExt};
use log::{debug, warn};
use once_cell::sync::OnceCell;
use reqwest::{Client, Method};
@ -120,7 +121,7 @@ impl super::Fetcher for GhCrateMeta {
.flat_map(move |pkg_url| self.launch_baseline_find_tasks(pkg_fmt, pkg_url, repo))
};
let handles: Vec<_> = if let Some(pkg_fmt) = self.data.meta.pkg_fmt {
let mut handles: FuturesUnordered<_> = if let Some(pkg_fmt) = self.data.meta.pkg_fmt {
launch_baseline_find_tasks(pkg_fmt).collect()
} else {
PkgFmt::iter()
@ -128,8 +129,8 @@ impl super::Fetcher for GhCrateMeta {
.collect()
};
for handle in handles {
if let Some((url, pkg_fmt)) = handle.await?? {
while let Some(res) = handles.next().await {
if let Some((url, pkg_fmt)) = res?? {
debug!("Winning URL is {url}, with pkg_fmt {pkg_fmt}");
self.resolution.set((url, pkg_fmt)).unwrap(); // find() is called first
return Ok(true);

View file

@ -169,10 +169,10 @@ async fn resolve_inner(
manifest.bin,
);
let mut fetchers = MultiFetcher::default();
let desired_targets = opts.desired_targets.get().await;
let mut fetchers = MultiFetcher::with_capacity(desired_targets.len() * 2);
for target in desired_targets {
debug!("Building metadata for target: {target}");
let mut target_meta = meta.clone_without_overrides();