Use global semaphores for concurrency limits (#18156)

Avoid problems such as https://github.com/astral-sh/uv/issues/15307,
follow-up to https://github.com/astral-sh/uv/pull/18054. See also
https://github.com/astral-sh/uv/pull/17633, for which this should be
helpful.
This commit is contained in:
konsti
2026-02-25 15:53:06 +01:00
committed by GitHub
parent c030397cac
commit 3697a2da18
28 changed files with 184 additions and 111 deletions
Generated
+1
View File
@@ -6171,6 +6171,7 @@ dependencies = [
"serde-untagged",
"serde_json",
"thiserror 2.0.18",
"tokio",
"tracing",
"url",
"uv-auth",
+6 -2
View File
@@ -203,7 +203,7 @@ mod resolver {
exclude_newer,
sources,
workspace_cache,
concurrency,
concurrency.clone(),
Preview::default(),
);
@@ -226,7 +226,11 @@ mod resolver {
&hashes,
&build_context,
installed_packages,
DistributionDatabase::new(client, &build_context, concurrency.downloads),
DistributionDatabase::new(
client,
&build_context,
concurrency.downloads_semaphore.clone(),
),
)?;
Ok(resolver.resolve().await?)
+3 -3
View File
@@ -223,11 +223,11 @@ pub struct SourceBuildContext {
}
impl SourceBuildContext {
/// Create a [`SourceBuildContext`] with the given concurrent build limit.
pub fn new(concurrent_builds: usize) -> Self {
/// Create a [`SourceBuildContext`] with the given shared concurrency semaphore.
pub fn new(concurrent_build_slots: Arc<Semaphore>) -> Self {
Self {
default_resolution: Arc::default(),
concurrent_build_slots: Arc::new(Semaphore::new(concurrent_builds)),
concurrent_build_slots,
}
}
}
+1
View File
@@ -37,6 +37,7 @@ rustc-hash = { workspace = true }
same-file = { workspace = true }
schemars = { workspace = true, optional = true }
serde = { workspace = true }
tokio = { workspace = true }
serde-untagged = { workspace = true }
thiserror = { workspace = true }
tracing = { workspace = true }
+34 -6
View File
@@ -1,7 +1,12 @@
use std::fmt;
use std::num::NonZeroUsize;
use std::sync::Arc;
use tokio::sync::Semaphore;
/// Concurrency limit settings.
#[derive(Copy, Clone, Debug)]
// TODO(konsti): We should find a pattern that doesn't require having both semaphores and counts.
#[derive(Clone)]
pub struct Concurrency {
/// The maximum number of concurrent downloads.
///
@@ -15,15 +20,27 @@ pub struct Concurrency {
///
/// Note this value must be non-zero.
pub installs: usize,
/// A global semaphore to limit the number of concurrent downloads.
pub downloads_semaphore: Arc<Semaphore>,
/// A global semaphore to limit the number of concurrent builds.
pub builds_semaphore: Arc<Semaphore>,
}
/// Custom `Debug` to hide semaphore fields from `--show-settings` output.
#[expect(clippy::missing_fields_in_debug)]
impl fmt::Debug for Concurrency {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Concurrency")
.field("downloads", &self.downloads)
.field("builds", &self.builds)
.field("installs", &self.installs)
.finish()
}
}
impl Default for Concurrency {
fn default() -> Self {
Self {
downloads: Self::DEFAULT_DOWNLOADS,
builds: Self::threads(),
installs: Self::threads(),
}
Self::new(Self::DEFAULT_DOWNLOADS, Self::threads(), Self::threads())
}
}
@@ -31,6 +48,17 @@ impl Concurrency {
// The default concurrent downloads limit.
pub const DEFAULT_DOWNLOADS: usize = 50;
/// Create a new [`Concurrency`] with the given limits.
pub fn new(downloads: usize, builds: usize, installs: usize) -> Self {
Self {
downloads,
builds,
installs,
downloads_semaphore: Arc::new(Semaphore::new(downloads)),
builds_semaphore: Arc::new(Semaphore::new(builds)),
}
}
// The default concurrent builds and install limit.
pub fn threads() -> usize {
std::thread::available_parallelism()
+13 -5
View File
@@ -147,7 +147,7 @@ impl<'a> BuildDispatch<'a> {
build_options,
hasher,
exclude_newer,
source_build_context: SourceBuildContext::new(concurrency.builds),
source_build_context: SourceBuildContext::new(concurrency.builds_semaphore.clone()),
build_extra_env_vars: FxHashMap::default(),
sources,
workspace_cache,
@@ -264,8 +264,12 @@ impl BuildContext for BuildDispatch<'_> {
self.hasher,
self,
EmptyInstalledPackages,
DistributionDatabase::new(self.client, self, self.concurrency.downloads)
.with_build_stack(build_stack),
DistributionDatabase::new(
self.client,
self,
self.concurrency.downloads_semaphore.clone(),
)
.with_build_stack(build_stack),
)?;
let resolution = Resolution::from(resolver.resolve().await.with_context(|| {
format!(
@@ -353,8 +357,12 @@ impl BuildContext for BuildDispatch<'_> {
tags,
self.hasher,
self.build_options,
DistributionDatabase::new(self.client, self, self.concurrency.downloads)
.with_build_stack(build_stack),
DistributionDatabase::new(
self.client,
self,
self.concurrency.downloads_semaphore.clone(),
)
.with_build_stack(build_stack),
);
debug!(
@@ -58,12 +58,12 @@ impl<'a, Context: BuildContext> DistributionDatabase<'a, Context> {
pub fn new(
client: &'a RegistryClient,
build_context: &'a Context,
concurrent_downloads: usize,
downloads_semaphore: Arc<Semaphore>,
) -> Self {
Self {
build_context,
builder: SourceDistributionBuilder::new(build_context),
client: ManagedClient::new(client, concurrent_downloads),
client: ManagedClient::new(client, downloads_semaphore),
reporter: None,
}
}
@@ -1151,15 +1151,15 @@ impl<'a, Context: BuildContext> DistributionDatabase<'a, Context> {
/// A wrapper around `RegistryClient` that manages a concurrency limit.
pub struct ManagedClient<'a> {
pub unmanaged: &'a RegistryClient,
control: Semaphore,
control: Arc<Semaphore>,
}
impl<'a> ManagedClient<'a> {
/// Create a new `ManagedClient` using the given client and concurrency limit.
fn new(client: &'a RegistryClient, concurrency: usize) -> Self {
/// Create a new `ManagedClient` using the given client and concurrency semaphore.
fn new(client: &'a RegistryClient, control: Arc<Semaphore>) -> Self {
ManagedClient {
unmanaged: client,
control: Semaphore::new(concurrency),
control,
}
}
+4 -4
View File
@@ -146,7 +146,7 @@ pub(crate) async fn build_frontend(
no_config,
python_preference,
python_downloads,
concurrency,
&concurrency,
cache,
printer,
preview,
@@ -193,7 +193,7 @@ async fn build_impl(
no_config: bool,
python_preference: PythonPreference,
python_downloads: PythonDownloads,
concurrency: Concurrency,
concurrency: &Concurrency,
cache: &Cache,
printer: Printer,
preview: Preview,
@@ -469,7 +469,7 @@ async fn build_package(
keyring_provider: KeyringProviderType,
exclude_newer: ExcludeNewer,
sources: NoSources,
concurrency: Concurrency,
concurrency: &Concurrency,
build_options: &BuildOptions,
sdist: bool,
wheel: bool,
@@ -630,7 +630,7 @@ async fn build_package(
exclude_newer,
sources.clone(),
workspace_cache,
concurrency,
concurrency.clone(),
preview,
);
+2 -2
View File
@@ -540,7 +540,7 @@ pub(crate) async fn pip_compile(
exclude_newer.clone(),
sources,
WorkspaceCache::default(),
concurrency,
concurrency.clone(),
preview,
);
@@ -580,7 +580,7 @@ pub(crate) async fn pip_compile(
&flat_index,
&top_level_index,
&build_dispatch,
concurrency,
&concurrency,
options,
Box::new(DefaultResolveLogger),
printer,
+4 -4
View File
@@ -486,7 +486,7 @@ pub(crate) async fn pip_install(
exclude_newer.clone(),
sources.clone(),
WorkspaceCache::default(),
concurrency,
concurrency.clone(),
preview,
);
@@ -595,7 +595,7 @@ pub(crate) async fn pip_install(
&flat_index,
state.index(),
&build_dispatch,
concurrency,
&concurrency,
options,
Box::new(DefaultResolveLogger),
printer,
@@ -640,7 +640,7 @@ pub(crate) async fn pip_install(
exclude_newer.clone(),
sources,
WorkspaceCache::default(),
concurrency,
concurrency.clone(),
preview,
);
@@ -658,7 +658,7 @@ pub(crate) async fn pip_install(
&tags,
&client,
state.in_flight(),
concurrency,
&concurrency,
&build_dispatch,
&cache,
&environment,
+1 -2
View File
@@ -7,7 +7,6 @@ use itertools::Itertools;
use owo_colors::OwoColorize;
use rustc_hash::{FxHashMap, FxHashSet};
use serde::Serialize;
use tokio::sync::Semaphore;
use tracing::debug;
use unicode_width::UnicodeWidthStr;
@@ -117,7 +116,7 @@ pub(crate) async fn pip_list(
.markers(environment.interpreter().markers())
.platform(environment.interpreter().platform())
.build();
let download_concurrency = Semaphore::new(concurrency.downloads);
let download_concurrency = concurrency.downloads_semaphore.clone();
// Determine the platform tags.
let interpreter = environment.interpreter();
+34 -10
View File
@@ -128,7 +128,7 @@ pub(crate) async fn resolve<InstalledPackages: InstalledPackagesProvider>(
flat_index: &FlatIndex,
index: &InMemoryIndex,
build_dispatch: &BuildDispatch<'_>,
concurrency: Concurrency,
concurrency: &Concurrency,
options: Options,
logger: Box<dyn ResolveLogger>,
printer: Printer,
@@ -156,7 +156,11 @@ pub(crate) async fn resolve<InstalledPackages: InstalledPackagesProvider>(
NamedRequirementsResolver::new(
hasher,
index,
DistributionDatabase::new(client, build_dispatch, concurrency.downloads),
DistributionDatabase::new(
client,
build_dispatch,
concurrency.downloads_semaphore.clone(),
),
)
.with_reporter(Arc::new(ResolverReporter::from(printer)))
.resolve(unnamed.into_iter())
@@ -170,7 +174,11 @@ pub(crate) async fn resolve<InstalledPackages: InstalledPackagesProvider>(
extras,
hasher,
index,
DistributionDatabase::new(client, build_dispatch, concurrency.downloads),
DistributionDatabase::new(
client,
build_dispatch,
concurrency.downloads_semaphore.clone(),
),
)
.with_reporter(Arc::new(ResolverReporter::from(printer)))
.resolve(source_trees.iter())
@@ -278,7 +286,11 @@ pub(crate) async fn resolve<InstalledPackages: InstalledPackagesProvider>(
NamedRequirementsResolver::new(
hasher,
index,
DistributionDatabase::new(client, build_dispatch, concurrency.downloads),
DistributionDatabase::new(
client,
build_dispatch,
concurrency.downloads_semaphore.clone(),
),
)
.with_reporter(Arc::new(ResolverReporter::from(printer)))
.resolve(unnamed.into_iter())
@@ -309,7 +321,11 @@ pub(crate) async fn resolve<InstalledPackages: InstalledPackagesProvider>(
&overrides,
hasher,
index,
DistributionDatabase::new(client, build_dispatch, concurrency.downloads),
DistributionDatabase::new(
client,
build_dispatch,
concurrency.downloads_semaphore.clone(),
),
)
.with_reporter(Arc::new(ResolverReporter::from(printer)))
.resolve(&resolver_env)
@@ -357,7 +373,11 @@ pub(crate) async fn resolve<InstalledPackages: InstalledPackagesProvider>(
hasher,
build_dispatch,
installed_packages,
DistributionDatabase::new(client, build_dispatch, concurrency.downloads),
DistributionDatabase::new(
client,
build_dispatch,
concurrency.downloads_semaphore.clone(),
),
)?
.with_reporter(Arc::new(reporter));
@@ -544,7 +564,7 @@ pub(crate) async fn install(
tags: &Tags,
client: &RegistryClient,
in_flight: &InFlight,
concurrency: Concurrency,
concurrency: &Concurrency,
build_dispatch: &BuildDispatch<'_>,
cache: &Cache,
venv: &PythonEnvironment,
@@ -685,7 +705,7 @@ pub(crate) async fn install(
}
if compile {
compile_bytecode(venv, &concurrency, cache, printer).await?;
compile_bytecode(venv, concurrency, cache, printer).await?;
}
// Construct a summary of the changes made to the environment.
@@ -722,7 +742,7 @@ async fn execute_plan(
tags: &Tags,
client: &RegistryClient,
in_flight: &InFlight,
concurrency: Concurrency,
concurrency: &Concurrency,
build_dispatch: &BuildDispatch<'_>,
cache: &Cache,
venv: &PythonEnvironment,
@@ -749,7 +769,11 @@ async fn execute_plan(
tags,
hasher,
build_options,
DistributionDatabase::new(client, build_dispatch, concurrency.downloads),
DistributionDatabase::new(
client,
build_dispatch,
concurrency.downloads_semaphore.clone(),
),
)
.with_reporter(Arc::new(
PrepareReporter::from(printer).with_length(remote.len() as u64),
+4 -4
View File
@@ -393,7 +393,7 @@ pub(crate) async fn pip_sync(
exclude_newer.clone(),
sources.clone(),
WorkspaceCache::default(),
concurrency,
concurrency.clone(),
preview,
);
@@ -486,7 +486,7 @@ pub(crate) async fn pip_sync(
&flat_index,
state.index(),
&build_dispatch,
concurrency,
&concurrency,
options,
Box::new(DefaultResolveLogger),
printer,
@@ -531,7 +531,7 @@ pub(crate) async fn pip_sync(
exclude_newer.clone(),
sources,
WorkspaceCache::default(),
concurrency,
concurrency.clone(),
preview,
);
@@ -549,7 +549,7 @@ pub(crate) async fn pip_sync(
&tags,
&client,
state.in_flight(),
concurrency,
&concurrency,
&build_dispatch,
&cache,
&environment,
+1 -2
View File
@@ -9,7 +9,6 @@ use petgraph::Direction;
use petgraph::graph::{EdgeIndex, NodeIndex};
use petgraph::prelude::EdgeRef;
use rustc_hash::{FxHashMap, FxHashSet};
use tokio::sync::Semaphore;
use uv_cache::{Cache, Refresh};
use uv_cache_info::Timestamp;
@@ -100,7 +99,7 @@ pub(crate) async fn pip_tree(
.markers(environment.interpreter().markers())
.platform(environment.interpreter().platform())
.build();
let download_concurrency = Semaphore::new(concurrency.downloads);
let download_concurrency = concurrency.downloads_semaphore.clone();
// Determine the platform tags.
let interpreter = environment.interpreter();
+8 -4
View File
@@ -459,7 +459,7 @@ pub(crate) async fn add(
sources,
// No workspace caching since `uv add` changes the workspace definition.
WorkspaceCache::default(),
concurrency,
concurrency.clone(),
preview,
);
@@ -467,7 +467,11 @@ pub(crate) async fn add(
NamedRequirementsResolver::new(
&hasher,
state.index(),
DistributionDatabase::new(&client, &build_dispatch, concurrency.downloads),
DistributionDatabase::new(
&client,
&build_dispatch,
concurrency.downloads_semaphore.clone(),
),
)
.with_reporter(Arc::new(ResolverReporter::from(printer)))
.resolve(unnamed.into_iter())
@@ -750,7 +754,7 @@ pub(crate) async fn add(
&settings,
&client_builder,
installer_metadata,
concurrency,
&concurrency,
cache,
printer,
preview,
@@ -992,7 +996,7 @@ async fn lock_and_sync(
settings: &ResolverInstallerSettings,
client_builder: &BaseClientBuilder<'_>,
installer_metadata: bool,
concurrency: Concurrency,
concurrency: &Concurrency,
cache: &Cache,
printer: Printer,
preview: Preview,
@@ -119,7 +119,7 @@ impl CachedEnvironment {
resolve: Box<dyn ResolveLogger>,
install: Box<dyn InstallLogger>,
installer_metadata: bool,
concurrency: Concurrency,
concurrency: &Concurrency,
cache: &Cache,
printer: Printer,
preview: Preview,
+1 -1
View File
@@ -208,7 +208,7 @@ pub(crate) async fn export(
&client_builder,
&state,
Box::new(DefaultResolveLogger),
concurrency,
&concurrency,
cache,
&workspace_cache,
printer,
+10 -6
View File
@@ -196,7 +196,7 @@ pub(crate) async fn lock(
&client_builder,
&state,
Box::new(DefaultResolveLogger),
concurrency,
&concurrency,
cache,
&workspace_cache,
printer,
@@ -288,7 +288,7 @@ pub(super) struct LockOperation<'env> {
client_builder: &'env BaseClientBuilder<'env>,
state: &'env UniversalState,
logger: Box<dyn ResolveLogger>,
concurrency: Concurrency,
concurrency: &'env Concurrency,
cache: &'env Cache,
workspace_cache: &'env WorkspaceCache,
printer: Printer,
@@ -303,7 +303,7 @@ impl<'env> LockOperation<'env> {
client_builder: &'env BaseClientBuilder<'env>,
state: &'env UniversalState,
logger: Box<dyn ResolveLogger>,
concurrency: Concurrency,
concurrency: &'env Concurrency,
cache: &'env Cache,
workspace_cache: &'env WorkspaceCache,
printer: Printer,
@@ -459,7 +459,7 @@ async fn do_lock(
client_builder: &BaseClientBuilder<'_>,
state: &UniversalState,
logger: Box<dyn ResolveLogger>,
concurrency: Concurrency,
concurrency: &Concurrency,
cache: &Cache,
workspace_cache: &WorkspaceCache,
printer: Printer,
@@ -783,11 +783,15 @@ async fn do_lock(
exclude_newer.clone(),
sources.clone(),
workspace_cache.clone(),
concurrency,
concurrency.clone(),
preview,
);
let database = DistributionDatabase::new(&client, &build_dispatch, concurrency.downloads);
let database = DistributionDatabase::new(
&client,
&build_dispatch,
concurrency.downloads_semaphore.clone(),
);
// If any of the resolution-determining settings changed, invalidate the lock.
let existing_lock = if let Some(existing_lock) = existing_lock {
+13 -9
View File
@@ -1793,7 +1793,7 @@ pub(crate) async fn resolve_names(
settings: &ResolverInstallerSettings,
client_builder: &BaseClientBuilder<'_>,
state: &SharedState,
concurrency: Concurrency,
concurrency: &Concurrency,
cache: &Cache,
workspace_cache: &WorkspaceCache,
printer: Printer,
@@ -1919,7 +1919,7 @@ pub(crate) async fn resolve_names(
exclude_newer.clone(),
sources.clone(),
workspace_cache.clone(),
concurrency,
concurrency.clone(),
preview,
);
@@ -1928,7 +1928,11 @@ pub(crate) async fn resolve_names(
NamedRequirementsResolver::new(
&hasher,
state.index(),
DistributionDatabase::new(&client, &build_dispatch, concurrency.downloads),
DistributionDatabase::new(
&client,
&build_dispatch,
concurrency.downloads_semaphore.clone(),
),
)
.with_reporter(Arc::new(ResolverReporter::from(printer)))
.resolve(unnamed.into_iter())
@@ -1987,7 +1991,7 @@ pub(crate) async fn resolve_environment(
client_builder: &BaseClientBuilder<'_>,
state: &PlatformState,
logger: Box<dyn ResolveLogger>,
concurrency: Concurrency,
concurrency: &Concurrency,
cache: &Cache,
printer: Printer,
preview: Preview,
@@ -2155,7 +2159,7 @@ pub(crate) async fn resolve_environment(
exclude_newer.clone(),
sources.clone(),
workspace_cache,
concurrency,
concurrency.clone(),
preview,
);
@@ -2203,7 +2207,7 @@ pub(crate) async fn sync_environment(
state: &PlatformState,
logger: Box<dyn InstallLogger>,
installer_metadata: bool,
concurrency: Concurrency,
concurrency: &Concurrency,
cache: &Cache,
printer: Printer,
preview: Preview,
@@ -2294,7 +2298,7 @@ pub(crate) async fn sync_environment(
exclude_newer.clone(),
sources,
workspace_cache,
concurrency,
concurrency.clone(),
preview,
);
@@ -2360,7 +2364,7 @@ pub(crate) async fn update_environment(
resolve: Box<dyn ResolveLogger>,
install: Box<dyn InstallLogger>,
installer_metadata: bool,
concurrency: Concurrency,
concurrency: &Concurrency,
cache: &Cache,
workspace_cache: WorkspaceCache,
dry_run: DryRun,
@@ -2550,7 +2554,7 @@ pub(crate) async fn update_environment(
exclude_newer.clone(),
sources.clone(),
workspace_cache,
concurrency,
concurrency.clone(),
preview,
);
+2 -2
View File
@@ -307,7 +307,7 @@ pub(crate) async fn remove(
&client_builder,
&state,
Box::new(DefaultResolveLogger),
concurrency,
&concurrency,
cache,
&WorkspaceCache::default(),
printer,
@@ -365,7 +365,7 @@ pub(crate) async fn remove(
&state,
Box::new(DefaultInstallLogger),
installer_metadata,
concurrency,
&concurrency,
cache,
WorkspaceCache::default(),
DryRun::Disabled,
+6 -6
View File
@@ -282,7 +282,7 @@ hint: If you are running a script with `{}` in the shebang, you may need to incl
} else {
Box::new(SummaryResolveLogger)
},
concurrency,
&concurrency,
&cache,
&workspace_cache,
printer,
@@ -330,7 +330,7 @@ hint: If you are running a script with `{}` in the shebang, you may need to incl
Box::new(SummaryInstallLogger)
},
installer_metadata,
concurrency,
&concurrency,
&cache,
workspace_cache.clone(),
DryRun::Disabled,
@@ -447,7 +447,7 @@ hint: If you are running a script with `{}` in the shebang, you may need to incl
Box::new(SummaryInstallLogger)
},
installer_metadata,
concurrency,
&concurrency,
&cache,
workspace_cache.clone(),
DryRun::Disabled,
@@ -784,7 +784,7 @@ hint: If you are running a script with `{}` in the shebang, you may need to incl
} else {
Box::new(SummaryResolveLogger)
},
concurrency,
&concurrency,
&cache,
&workspace_cache,
printer,
@@ -873,7 +873,7 @@ hint: If you are running a script with `{}` in the shebang, you may need to incl
Box::new(SummaryInstallLogger)
},
installer_metadata,
concurrency,
&concurrency,
&cache,
workspace_cache.clone(),
DryRun::Disabled,
@@ -1028,7 +1028,7 @@ hint: If you are running a script with `{}` in the shebang, you may need to incl
Box::new(SummaryInstallLogger)
},
installer_metadata,
concurrency,
&concurrency,
&cache,
printer,
preview,
+5 -5
View File
@@ -283,7 +283,7 @@ pub(crate) async fn sync(
Box::new(DefaultResolveLogger),
Box::new(DefaultInstallLogger),
installer_metadata,
concurrency,
&concurrency,
cache,
workspace_cache.clone(),
dry_run,
@@ -350,7 +350,7 @@ pub(crate) async fn sync(
&client_builder,
&state,
Box::new(DefaultResolveLogger),
concurrency,
&concurrency,
cache,
&workspace_cache,
printer,
@@ -410,7 +410,7 @@ pub(crate) async fn sync(
&state,
Box::new(DefaultInstallLogger),
installer_metadata,
concurrency,
&concurrency,
cache,
workspace_cache,
dry_run,
@@ -613,7 +613,7 @@ pub(super) async fn do_sync(
state: &PlatformState,
logger: Box<dyn InstallLogger>,
installer_metadata: bool,
concurrency: Concurrency,
concurrency: &Concurrency,
cache: &Cache,
workspace_cache: WorkspaceCache,
dry_run: DryRun,
@@ -815,7 +815,7 @@ pub(super) async fn do_sync(
exclude_newer.clone(),
sources.clone(),
workspace_cache.clone(),
concurrency,
concurrency.clone(),
preview,
);
+2 -3
View File
@@ -3,7 +3,6 @@ use std::path::Path;
use anstream::print;
use anyhow::{Error, Result};
use futures::StreamExt;
use tokio::sync::Semaphore;
use uv_cache::{Cache, Refresh};
use uv_cache_info::Timestamp;
use uv_client::{BaseClientBuilder, RegistryClientBuilder};
@@ -147,7 +146,7 @@ pub(crate) async fn tree(
client_builder,
&state,
Box::new(DefaultResolveLogger),
concurrency,
&concurrency,
cache,
&WorkspaceCache::default(),
printer,
@@ -226,7 +225,7 @@ pub(crate) async fn tree(
.index_locations(index_locations.clone())
.keyring(*keyring_provider)
.build();
let download_concurrency = Semaphore::new(concurrency.downloads);
let download_concurrency = concurrency.downloads_semaphore.clone();
// Initialize the client to fetch the latest version of each package.
let client = LatestClient {
+4 -4
View File
@@ -107,7 +107,7 @@ pub(crate) async fn project_version(
client_builder,
python_preference,
python_downloads,
concurrency,
&concurrency,
no_config,
cache,
short,
@@ -328,7 +328,7 @@ pub(crate) async fn project_version(
python_preference,
python_downloads,
installer_metadata,
concurrency,
&concurrency,
no_config,
cache,
printer,
@@ -437,7 +437,7 @@ async fn print_frozen_version(
client_builder: BaseClientBuilder<'_>,
python_preference: PythonPreference,
python_downloads: PythonDownloads,
concurrency: Concurrency,
concurrency: &Concurrency,
no_config: bool,
cache: &Cache,
short: bool,
@@ -535,7 +535,7 @@ async fn lock_and_sync(
python_preference: PythonPreference,
python_downloads: PythonDownloads,
installer_metadata: bool,
concurrency: Concurrency,
concurrency: &Concurrency,
no_config: bool,
cache: &Cache,
printer: Printer,
+8 -9
View File
@@ -3,7 +3,6 @@ use std::str::FromStr;
use anyhow::{Result, bail};
use owo_colors::OwoColorize;
use tokio::sync::Semaphore;
use tracing::{debug, trace};
use uv_cache::{Cache, Refresh};
@@ -174,7 +173,7 @@ pub(crate) async fn install(
&settings,
&client_builder,
&state,
concurrency,
&concurrency,
&cache,
&workspace_cache,
printer,
@@ -275,7 +274,7 @@ pub(crate) async fn install(
// Initialize the capabilities.
let capabilities = IndexCapabilities::default();
let download_concurrency = Semaphore::new(concurrency.downloads);
let download_concurrency = concurrency.downloads_semaphore.clone();
// Initialize the client to fetch the latest version.
let latest_client = LatestClient {
@@ -362,7 +361,7 @@ pub(crate) async fn install(
&settings,
&client_builder,
&state,
concurrency,
&concurrency,
&cache,
&workspace_cache,
printer,
@@ -388,7 +387,7 @@ pub(crate) async fn install(
&settings,
&client_builder,
&state,
concurrency,
&concurrency,
&cache,
&workspace_cache,
printer,
@@ -578,7 +577,7 @@ pub(crate) async fn install(
Box::new(DefaultResolveLogger),
Box::new(DefaultInstallLogger),
installer_metadata,
concurrency,
&concurrency,
&cache,
workspace_cache,
DryRun::Disabled,
@@ -619,7 +618,7 @@ pub(crate) async fn install(
&client_builder,
&state,
Box::new(DefaultResolveLogger),
concurrency,
&concurrency,
&cache,
printer,
preview,
@@ -674,7 +673,7 @@ pub(crate) async fn install(
&client_builder,
&state,
Box::new(DefaultResolveLogger),
concurrency,
&concurrency,
&cache,
printer,
preview,
@@ -715,7 +714,7 @@ pub(crate) async fn install(
&state,
Box::new(DefaultInstallLogger),
installer_metadata,
concurrency,
&concurrency,
&cache,
printer,
preview,
+3 -4
View File
@@ -10,7 +10,6 @@ use console::Term;
use itertools::Itertools;
use owo_colors::OwoColorize;
use tokio::process::Command;
use tokio::sync::Semaphore;
use tracing::{debug, warn};
use uv_cache::{Cache, Refresh};
@@ -304,7 +303,7 @@ pub(crate) async fn run(
python_preference,
python_downloads,
installer_metadata,
concurrency,
&concurrency,
&cache,
printer,
preview,
@@ -736,7 +735,7 @@ async fn get_or_create_environment(
python_preference: PythonPreference,
python_downloads: PythonDownloads,
installer_metadata: bool,
concurrency: Concurrency,
concurrency: &Concurrency,
cache: &Cache,
printer: Printer,
preview: Preview,
@@ -929,7 +928,7 @@ async fn get_or_create_environment(
// Initialize the capabilities.
let capabilities = IndexCapabilities::default();
let download_concurrency = Semaphore::new(concurrency.downloads);
let download_concurrency = concurrency.downloads_semaphore.clone();
// Initialize the client to fetch the latest version.
let latest_client = LatestClient {
+2 -2
View File
@@ -133,7 +133,7 @@ pub(crate) async fn upgrade(
cache,
&filesystem,
installer_metadata,
concurrency,
&concurrency,
preview,
))
.await;
@@ -268,7 +268,7 @@ async fn upgrade_tool(
cache: &Cache,
filesystem: &ResolverInstallerOptions,
installer_metadata: bool,
concurrency: Concurrency,
concurrency: &Concurrency,
preview: Preview,
) -> Result<UpgradeReport> {
// Ensure the tool is installed.
+5 -5
View File
@@ -123,26 +123,26 @@ impl GlobalSettings {
ColorChoice::Auto
},
network_settings,
concurrency: Concurrency {
downloads: environment
concurrency: Concurrency::new(
environment
.concurrency
.downloads
.combine(workspace.and_then(|workspace| workspace.globals.concurrent_downloads))
.map(NonZeroUsize::get)
.unwrap_or(Concurrency::DEFAULT_DOWNLOADS),
builds: environment
environment
.concurrency
.builds
.combine(workspace.and_then(|workspace| workspace.globals.concurrent_builds))
.map(NonZeroUsize::get)
.unwrap_or_else(Concurrency::threads),
installs: environment
environment
.concurrency
.installs
.combine(workspace.and_then(|workspace| workspace.globals.concurrent_installs))
.map(NonZeroUsize::get)
.unwrap_or_else(Concurrency::threads),
},
),
show_settings: args.show_settings,
preview: Preview::from_args(
resolve_preview(args, workspace, environment),