Skip to content

Commit 72ed97b

Browse files
committed
Run the is_yanked check in parallel for better performance with -Z sparse-registry
1 parent c0bbd42 commit 72ed97b

File tree

9 files changed

+83
-39
lines changed

9 files changed

+83
-39
lines changed

src/cargo/core/source/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ pub trait Source {
103103

104104
/// Query if a package is yanked. Only registry sources can mark packages
105105
/// as yanked. This ignores the yanked whitelist.
106-
fn is_yanked(&mut self, _pkg: PackageId) -> CargoResult<bool>;
106+
fn is_yanked(&mut self, _pkg: PackageId) -> Poll<CargoResult<bool>>;
107107

108108
/// Block until all outstanding Poll::Pending requests are `Poll::Ready`.
109109
///
@@ -190,7 +190,7 @@ impl<'a, T: Source + ?Sized + 'a> Source for Box<T> {
190190
(**self).add_to_yanked_whitelist(pkgs);
191191
}
192192

193-
fn is_yanked(&mut self, pkg: PackageId) -> CargoResult<bool> {
193+
fn is_yanked(&mut self, pkg: PackageId) -> Poll<CargoResult<bool>> {
194194
(**self).is_yanked(pkg)
195195
}
196196

@@ -260,7 +260,7 @@ impl<'a, T: Source + ?Sized + 'a> Source for &'a mut T {
260260
(**self).add_to_yanked_whitelist(pkgs);
261261
}
262262

263-
fn is_yanked(&mut self, pkg: PackageId) -> CargoResult<bool> {
263+
fn is_yanked(&mut self, pkg: PackageId) -> Poll<CargoResult<bool>> {
264264
(**self).is_yanked(pkg)
265265
}
266266

src/cargo/ops/cargo_install.rs

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
22
use std::path::{Path, PathBuf};
33
use std::sync::Arc;
4+
use std::task::Poll;
45
use std::{env, fs};
56

67
use crate::core::compiler::{CompileKind, DefaultExecutor, Executor, Freshness, UnitOutput};
@@ -530,22 +531,40 @@ impl<'cfg, 'a> InstallablePackage<'cfg, 'a> {
530531
// duplicate "Updating", but since `source` is taken by value, then it
531532
// wouldn't be available for `compile_ws`.
532533
let (pkg_set, resolve) = ops::resolve_ws(&self.ws)?;
533-
let mut sources = pkg_set.sources_mut();
534534

535535
// Checking the yanked status involves taking a look at the registry and
536536
// maybe updating files, so be sure to lock it here.
537537
let _lock = self.ws.config().acquire_package_cache_lock()?;
538538

539-
for pkg_id in resolve.iter() {
540-
if let Some(source) = sources.get_mut(pkg_id.source_id()) {
541-
if source.is_yanked(pkg_id)? {
542-
self.ws.config().shell().warn(format!(
543-
"package `{}` in Cargo.lock is yanked in registry `{}`, \
544-
consider running without --locked",
545-
pkg_id,
546-
pkg_id.source_id().display_registry_name()
547-
))?;
539+
let mut sources = pkg_set.sources_mut();
540+
let mut pending: Vec<PackageId> = resolve.iter().collect();
541+
let mut results = Vec::new();
542+
for (_id, source) in sources.sources_mut() {
543+
source.invalidate_cache();
544+
}
545+
while !pending.is_empty() {
546+
pending.retain(|pkg_id| {
547+
if let Some(source) = sources.get_mut(pkg_id.source_id()) {
548+
match source.is_yanked(*pkg_id) {
549+
Poll::Ready(result) => results.push((*pkg_id, result)),
550+
Poll::Pending => return true,
551+
}
548552
}
553+
false
554+
});
555+
for (_id, source) in sources.sources_mut() {
556+
source.block_until_ready()?;
557+
}
558+
}
559+
560+
for (pkg_id, is_yanked) in results {
561+
if is_yanked? {
562+
self.ws.config().shell().warn(format!(
563+
"package `{}` in Cargo.lock is yanked in registry `{}`, \
564+
consider running without --locked",
565+
pkg_id,
566+
pkg_id.source_id().display_registry_name()
567+
))?;
549568
}
550569
}
551570

src/cargo/ops/cargo_package.rs

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use std::io::SeekFrom;
55
use std::path::{Path, PathBuf};
66
use std::rc::Rc;
77
use std::sync::Arc;
8+
use std::task::Poll;
89

910
use crate::core::compiler::{BuildConfig, CompileMode, DefaultExecutor, Executor};
1011
use crate::core::resolver::CliFeatures;
@@ -722,16 +723,34 @@ fn check_yanked(config: &Config, pkg_set: &PackageSet<'_>, resolve: &Resolve) ->
722723
let _lock = config.acquire_package_cache_lock()?;
723724

724725
let mut sources = pkg_set.sources_mut();
725-
for pkg_id in resolve.iter() {
726-
if let Some(source) = sources.get_mut(pkg_id.source_id()) {
727-
if source.is_yanked(pkg_id)? {
728-
config.shell().warn(format!(
729-
"package `{}` in Cargo.lock is yanked in registry `{}`, \
730-
consider updating to a version that is not yanked",
731-
pkg_id,
732-
pkg_id.source_id().display_registry_name()
733-
))?;
726+
let mut pending: Vec<PackageId> = resolve.iter().collect();
727+
let mut results = Vec::new();
728+
for (_id, source) in sources.sources_mut() {
729+
source.invalidate_cache();
730+
}
731+
while !pending.is_empty() {
732+
pending.retain(|pkg_id| {
733+
if let Some(source) = sources.get_mut(pkg_id.source_id()) {
734+
match source.is_yanked(*pkg_id) {
735+
Poll::Ready(result) => results.push((*pkg_id, result)),
736+
Poll::Pending => return true,
737+
}
734738
}
739+
false
740+
});
741+
for (_id, source) in sources.sources_mut() {
742+
source.block_until_ready()?;
743+
}
744+
}
745+
746+
for (pkg_id, is_yanked) in results {
747+
if is_yanked? {
748+
config.shell().warn(format!(
749+
"package `{}` in Cargo.lock is yanked in registry `{}`, \
750+
consider updating to a version that is not yanked",
751+
pkg_id,
752+
pkg_id.source_id().display_registry_name()
753+
))?;
735754
}
736755
}
737756
Ok(())

src/cargo/ops/common_for_install_and_uninstall.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -553,8 +553,20 @@ where
553553
None => {
554554
let is_yanked: bool = if dep.version_req().is_exact() {
555555
let version: String = dep.version_req().to_string();
556-
PackageId::new(dep.package_name(), &version[1..], source.source_id())
557-
.map_or(false, |pkg_id| source.is_yanked(pkg_id).unwrap_or(false))
556+
if let Ok(pkg_id) =
557+
PackageId::new(dep.package_name(), &version[1..], source.source_id())
558+
{
559+
source.invalidate_cache();
560+
loop {
561+
match source.is_yanked(pkg_id) {
562+
Poll::Ready(Ok(is_yanked)) => break is_yanked,
563+
Poll::Ready(Err(_)) => break false,
564+
Poll::Pending => source.block_until_ready()?,
565+
}
566+
}
567+
} else {
568+
false
569+
}
558570
} else {
559571
false
560572
};

src/cargo/sources/directory.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,8 +219,8 @@ impl<'cfg> Source for DirectorySource<'cfg> {
219219

220220
fn add_to_yanked_whitelist(&mut self, _pkgs: &[PackageId]) {}
221221

222-
fn is_yanked(&mut self, _pkg: PackageId) -> CargoResult<bool> {
223-
Ok(false)
222+
fn is_yanked(&mut self, _pkg: PackageId) -> Poll<CargoResult<bool>> {
223+
Poll::Ready(Ok(false))
224224
}
225225

226226
fn invalidate_cache(&mut self) {

src/cargo/sources/git/source.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -234,8 +234,8 @@ impl<'cfg> Source for GitSource<'cfg> {
234234

235235
fn add_to_yanked_whitelist(&mut self, _pkgs: &[PackageId]) {}
236236

237-
fn is_yanked(&mut self, _pkg: PackageId) -> CargoResult<bool> {
238-
Ok(false)
237+
fn is_yanked(&mut self, _pkg: PackageId) -> Poll<CargoResult<bool>> {
238+
Poll::Ready(Ok(false))
239239
}
240240

241241
fn invalidate_cache(&mut self) {}

src/cargo/sources/path.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -562,8 +562,8 @@ impl<'cfg> Source for PathSource<'cfg> {
562562

563563
fn add_to_yanked_whitelist(&mut self, _pkgs: &[PackageId]) {}
564564

565-
fn is_yanked(&mut self, _pkg: PackageId) -> CargoResult<bool> {
566-
Ok(false)
565+
fn is_yanked(&mut self, _pkg: PackageId) -> Poll<CargoResult<bool>> {
566+
Poll::Ready(Ok(false))
567567
}
568568

569569
fn block_until_ready(&mut self) -> CargoResult<()> {

src/cargo/sources/registry/mod.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -801,14 +801,8 @@ impl<'cfg> Source for RegistrySource<'cfg> {
801801
self.yanked_whitelist.extend(pkgs);
802802
}
803803

804-
fn is_yanked(&mut self, pkg: PackageId) -> CargoResult<bool> {
805-
self.invalidate_cache();
806-
loop {
807-
match self.index.is_yanked(pkg, &mut *self.ops)? {
808-
Poll::Ready(yanked) => return Ok(yanked),
809-
Poll::Pending => self.block_until_ready()?,
810-
}
811-
}
804+
fn is_yanked(&mut self, pkg: PackageId) -> Poll<CargoResult<bool>> {
805+
self.index.is_yanked(pkg, &mut *self.ops)
812806
}
813807

814808
fn block_until_ready(&mut self) -> CargoResult<()> {

src/cargo/sources/replaced.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ impl<'cfg> Source for ReplacedSource<'cfg> {
134134
self.inner.add_to_yanked_whitelist(&pkgs);
135135
}
136136

137-
fn is_yanked(&mut self, pkg: PackageId) -> CargoResult<bool> {
137+
fn is_yanked(&mut self, pkg: PackageId) -> Poll<CargoResult<bool>> {
138138
self.inner.is_yanked(pkg)
139139
}
140140

0 commit comments

Comments
 (0)