]> git.proxmox.com Git - cargo.git/commitdiff
Run the is_yanked check in parallel for better performance with -Z sparse-registry
authorArlo Siemsen <arsiem@microsoft.com>
Wed, 6 Jul 2022 06:07:06 +0000 (01:07 -0500)
committerArlo Siemsen <arsiem@microsoft.com>
Wed, 6 Jul 2022 17:48:59 +0000 (12:48 -0500)
src/cargo/core/source/mod.rs
src/cargo/ops/cargo_install.rs
src/cargo/ops/cargo_package.rs
src/cargo/ops/common_for_install_and_uninstall.rs
src/cargo/sources/directory.rs
src/cargo/sources/git/source.rs
src/cargo/sources/path.rs
src/cargo/sources/registry/mod.rs
src/cargo/sources/replaced.rs

index e8393dc97a331e952a7a997405eb15083493ab80..56dfcb902aef978049a046779d36b3d054a4b5cf 100644 (file)
@@ -103,7 +103,7 @@ pub trait Source {
 
     /// Query if a package is yanked. Only registry sources can mark packages
     /// as yanked. This ignores the yanked whitelist.
-    fn is_yanked(&mut self, _pkg: PackageId) -> CargoResult<bool>;
+    fn is_yanked(&mut self, _pkg: PackageId) -> Poll<CargoResult<bool>>;
 
     /// Block until all outstanding Poll::Pending requests are `Poll::Ready`.
     ///
@@ -190,7 +190,7 @@ impl<'a, T: Source + ?Sized + 'a> Source for Box<T> {
         (**self).add_to_yanked_whitelist(pkgs);
     }
 
-    fn is_yanked(&mut self, pkg: PackageId) -> CargoResult<bool> {
+    fn is_yanked(&mut self, pkg: PackageId) -> Poll<CargoResult<bool>> {
         (**self).is_yanked(pkg)
     }
 
@@ -260,7 +260,7 @@ impl<'a, T: Source + ?Sized + 'a> Source for &'a mut T {
         (**self).add_to_yanked_whitelist(pkgs);
     }
 
-    fn is_yanked(&mut self, pkg: PackageId) -> CargoResult<bool> {
+    fn is_yanked(&mut self, pkg: PackageId) -> Poll<CargoResult<bool>> {
         (**self).is_yanked(pkg)
     }
 
index 0fea201b044048102b0f10a27070995605bf24a2..d6cb178f2d76d82b6c49b4c74fea78a88b473065 100644 (file)
@@ -1,6 +1,7 @@
 use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
 use std::path::{Path, PathBuf};
 use std::sync::Arc;
+use std::task::Poll;
 use std::{env, fs};
 
 use crate::core::compiler::{CompileKind, DefaultExecutor, Executor, Freshness, UnitOutput};
@@ -530,22 +531,40 @@ impl<'cfg, 'a> InstallablePackage<'cfg, 'a> {
         // duplicate "Updating", but since `source` is taken by value, then it
         // wouldn't be available for `compile_ws`.
         let (pkg_set, resolve) = ops::resolve_ws(&self.ws)?;
-        let mut sources = pkg_set.sources_mut();
 
         // Checking the yanked status involves taking a look at the registry and
         // maybe updating files, so be sure to lock it here.
         let _lock = self.ws.config().acquire_package_cache_lock()?;
 
-        for pkg_id in resolve.iter() {
-            if let Some(source) = sources.get_mut(pkg_id.source_id()) {
-                if source.is_yanked(pkg_id)? {
-                    self.ws.config().shell().warn(format!(
-                        "package `{}` in Cargo.lock is yanked in registry `{}`, \
-                         consider running without --locked",
-                        pkg_id,
-                        pkg_id.source_id().display_registry_name()
-                    ))?;
+        let mut sources = pkg_set.sources_mut();
+        let mut pending: Vec<PackageId> = resolve.iter().collect();
+        let mut results = Vec::new();
+        for (_id, source) in sources.sources_mut() {
+            source.invalidate_cache();
+        }
+        while !pending.is_empty() {
+            pending.retain(|pkg_id| {
+                if let Some(source) = sources.get_mut(pkg_id.source_id()) {
+                    match source.is_yanked(*pkg_id) {
+                        Poll::Ready(result) => results.push((*pkg_id, result)),
+                        Poll::Pending => return true,
+                    }
                 }
+                false
+            });
+            for (_id, source) in sources.sources_mut() {
+                source.block_until_ready()?;
+            }
+        }
+
+        for (pkg_id, is_yanked) in results {
+            if is_yanked? {
+                self.ws.config().shell().warn(format!(
+                    "package `{}` in Cargo.lock is yanked in registry `{}`, \
+                     consider running without --locked",
+                    pkg_id,
+                    pkg_id.source_id().display_registry_name()
+                ))?;
             }
         }
 
index 6b4dd2c2975f190c536a131316245e8abb9ab62e..da8504f1e4599948d53c9ef013f1bd3917ce599d 100644 (file)
@@ -5,6 +5,7 @@ use std::io::SeekFrom;
 use std::path::{Path, PathBuf};
 use std::rc::Rc;
 use std::sync::Arc;
+use std::task::Poll;
 
 use crate::core::compiler::{BuildConfig, CompileMode, DefaultExecutor, Executor};
 use crate::core::resolver::CliFeatures;
@@ -722,16 +723,34 @@ fn check_yanked(config: &Config, pkg_set: &PackageSet<'_>, resolve: &Resolve) ->
     let _lock = config.acquire_package_cache_lock()?;
 
     let mut sources = pkg_set.sources_mut();
-    for pkg_id in resolve.iter() {
-        if let Some(source) = sources.get_mut(pkg_id.source_id()) {
-            if source.is_yanked(pkg_id)? {
-                config.shell().warn(format!(
-                    "package `{}` in Cargo.lock is yanked in registry `{}`, \
-                     consider updating to a version that is not yanked",
-                    pkg_id,
-                    pkg_id.source_id().display_registry_name()
-                ))?;
+    let mut pending: Vec<PackageId> = resolve.iter().collect();
+    let mut results = Vec::new();
+    for (_id, source) in sources.sources_mut() {
+        source.invalidate_cache();
+    }
+    while !pending.is_empty() {
+        pending.retain(|pkg_id| {
+            if let Some(source) = sources.get_mut(pkg_id.source_id()) {
+                match source.is_yanked(*pkg_id) {
+                    Poll::Ready(result) => results.push((*pkg_id, result)),
+                    Poll::Pending => return true,
+                }
             }
+            false
+        });
+        for (_id, source) in sources.sources_mut() {
+            source.block_until_ready()?;
+        }
+    }
+
+    for (pkg_id, is_yanked) in results {
+        if is_yanked? {
+            config.shell().warn(format!(
+                "package `{}` in Cargo.lock is yanked in registry `{}`, \
+                 consider updating to a version that is not yanked",
+                pkg_id,
+                pkg_id.source_id().display_registry_name()
+            ))?;
         }
     }
     Ok(())
index fd456ae90ad13580848c79b41d920eb17504e02b..362a2d9645017cc4f64c3bbfebb4a83ae3e71687 100644 (file)
@@ -553,8 +553,20 @@ where
         None => {
             let is_yanked: bool = if dep.version_req().is_exact() {
                 let version: String = dep.version_req().to_string();
-                PackageId::new(dep.package_name(), &version[1..], source.source_id())
-                    .map_or(false, |pkg_id| source.is_yanked(pkg_id).unwrap_or(false))
+                if let Ok(pkg_id) =
+                    PackageId::new(dep.package_name(), &version[1..], source.source_id())
+                {
+                    source.invalidate_cache();
+                    loop {
+                        match source.is_yanked(pkg_id) {
+                            Poll::Ready(Ok(is_yanked)) => break is_yanked,
+                            Poll::Ready(Err(_)) => break false,
+                            Poll::Pending => source.block_until_ready()?,
+                        }
+                    }
+                } else {
+                    false
+                }
             } else {
                 false
             };
index 20eea5fad85c1c16d0196dc695fe92af88428a7c..d6f96cc90030d22eed806fe48ca4aac0863ea130 100644 (file)
@@ -219,8 +219,8 @@ impl<'cfg> Source for DirectorySource<'cfg> {
 
     fn add_to_yanked_whitelist(&mut self, _pkgs: &[PackageId]) {}
 
-    fn is_yanked(&mut self, _pkg: PackageId) -> CargoResult<bool> {
-        Ok(false)
+    fn is_yanked(&mut self, _pkg: PackageId) -> Poll<CargoResult<bool>> {
+        Poll::Ready(Ok(false))
     }
 
     fn invalidate_cache(&mut self) {
index 19a1274825c86e3ffd830b896b3d17b8daa044f5..5a8849990d19359b99447bcaba558374e1508d63 100644 (file)
@@ -234,8 +234,8 @@ impl<'cfg> Source for GitSource<'cfg> {
 
     fn add_to_yanked_whitelist(&mut self, _pkgs: &[PackageId]) {}
 
-    fn is_yanked(&mut self, _pkg: PackageId) -> CargoResult<bool> {
-        Ok(false)
+    fn is_yanked(&mut self, _pkg: PackageId) -> Poll<CargoResult<bool>> {
+        Poll::Ready(Ok(false))
     }
 
     fn invalidate_cache(&mut self) {}
index 7da89d7eeaa25449a33f244c1d70cb96730c30c5..fcbae46088e25a7e92497d63742d87464aeb654c 100644 (file)
@@ -562,8 +562,8 @@ impl<'cfg> Source for PathSource<'cfg> {
 
     fn add_to_yanked_whitelist(&mut self, _pkgs: &[PackageId]) {}
 
-    fn is_yanked(&mut self, _pkg: PackageId) -> CargoResult<bool> {
-        Ok(false)
+    fn is_yanked(&mut self, _pkg: PackageId) -> Poll<CargoResult<bool>> {
+        Poll::Ready(Ok(false))
     }
 
     fn block_until_ready(&mut self) -> CargoResult<()> {
index 413734e10ecb3f67d0f6baccf0b73991a14c4712..899c4e73c22cbbf349e2a5d637fa2399a0ee2554 100644 (file)
@@ -801,14 +801,8 @@ impl<'cfg> Source for RegistrySource<'cfg> {
         self.yanked_whitelist.extend(pkgs);
     }
 
-    fn is_yanked(&mut self, pkg: PackageId) -> CargoResult<bool> {
-        self.invalidate_cache();
-        loop {
-            match self.index.is_yanked(pkg, &mut *self.ops)? {
-                Poll::Ready(yanked) => return Ok(yanked),
-                Poll::Pending => self.block_until_ready()?,
-            }
-        }
+    fn is_yanked(&mut self, pkg: PackageId) -> Poll<CargoResult<bool>> {
+        self.index.is_yanked(pkg, &mut *self.ops)
     }
 
     fn block_until_ready(&mut self) -> CargoResult<()> {
index 29b0b6dfdc5a86c9552b7352de31264c40bb0e91..0bbbd6f181fe43dcaae26a1b33cd04b574a6ad49 100644 (file)
@@ -134,7 +134,7 @@ impl<'cfg> Source for ReplacedSource<'cfg> {
         self.inner.add_to_yanked_whitelist(&pkgs);
     }
 
-    fn is_yanked(&mut self, pkg: PackageId) -> CargoResult<bool> {
+    fn is_yanked(&mut self, pkg: PackageId) -> Poll<CargoResult<bool>> {
         self.inner.is_yanked(pkg)
     }