mirror of
https://github.com/astral-sh/uv.git
synced 2025-07-07 21:35:00 +00:00
Don't set a timeout by default
This commit is contained in:
parent
995fba8fec
commit
a8912c36e3
3 changed files with 58 additions and 35 deletions
|
@ -1,8 +1,8 @@
|
|||
use std::collections::BTreeMap;
|
||||
use std::env;
|
||||
use std::fmt::Debug;
|
||||
use std::path::Path;
|
||||
use std::str::FromStr;
|
||||
use std::time::Duration;
|
||||
|
||||
use async_http_range_reader::AsyncHttpRangeReader;
|
||||
use futures::{FutureExt, TryStreamExt};
|
||||
|
@ -25,7 +25,6 @@ use pypi_types::{Metadata21, SimpleJson};
|
|||
use uv_auth::safe_copy_url_auth;
|
||||
use uv_cache::{Cache, CacheBucket, WheelCache};
|
||||
use uv_normalize::PackageName;
|
||||
use uv_warnings::warn_user_once;
|
||||
|
||||
use crate::cached_client::CacheControl;
|
||||
use crate::html::SimpleHtml;
|
||||
|
@ -41,6 +40,7 @@ pub struct RegistryClientBuilder {
|
|||
retries: u32,
|
||||
connectivity: Connectivity,
|
||||
cache: Cache,
|
||||
timeout: Option<Duration>,
|
||||
client: Option<Client>,
|
||||
}
|
||||
|
||||
|
@ -51,6 +51,7 @@ impl RegistryClientBuilder {
|
|||
cache,
|
||||
connectivity: Connectivity::Online,
|
||||
retries: 3,
|
||||
timeout: None,
|
||||
client: None,
|
||||
}
|
||||
}
|
||||
|
@ -87,30 +88,22 @@ impl RegistryClientBuilder {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn build(self) -> RegistryClient {
|
||||
// Timeout options, matching https://doc.rust-lang.org/nightly/cargo/reference/config.html#httptimeout
|
||||
// `UV_REQUEST_TIMEOUT` is provided for backwards compatibility with v0.1.6
|
||||
let default_timeout = 5 * 60;
|
||||
let timeout = env::var("UV_HTTP_TIMEOUT")
|
||||
.or_else(|_| env::var("UV_REQUEST_TIMEOUT"))
|
||||
.or_else(|_| env::var("HTTP_TIMEOUT"))
|
||||
.and_then(|value| {
|
||||
value.parse::<u64>()
|
||||
.or_else(|_| {
|
||||
// On parse error, warn and use the default timeout
|
||||
warn_user_once!("Ignoring invalid value from environment for UV_HTTP_TIMEOUT. Expected integer number of seconds, got \"{value}\".");
|
||||
Ok(default_timeout)
|
||||
})
|
||||
})
|
||||
.unwrap_or(default_timeout);
|
||||
debug!("Using registry request timeout of {}s", timeout);
|
||||
#[must_use]
|
||||
pub fn timeout(mut self, timeout: Duration) -> Self {
|
||||
self.timeout = Some(timeout);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(self) -> RegistryClient {
|
||||
let client_raw = self.client.unwrap_or_else(|| {
|
||||
// Disallow any connections.
|
||||
let client_core = ClientBuilder::new()
|
||||
let mut client_core = ClientBuilder::new()
|
||||
.user_agent("uv")
|
||||
.pool_max_idle_per_host(20)
|
||||
.timeout(std::time::Duration::from_secs(timeout));
|
||||
.pool_max_idle_per_host(20);
|
||||
if let Some(timeout) = self.timeout {
|
||||
debug!("Using registry request timeout of {}s", timeout.as_secs());
|
||||
client_core = client_core.timeout(timeout);
|
||||
}
|
||||
|
||||
client_core.build().expect("Failed to build HTTP client.")
|
||||
});
|
||||
|
@ -135,7 +128,7 @@ impl RegistryClientBuilder {
|
|||
connectivity: self.connectivity,
|
||||
client_raw,
|
||||
client: CachedClient::new(uncached_client),
|
||||
timeout,
|
||||
timeout: self.timeout,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -155,7 +148,7 @@ pub struct RegistryClient {
|
|||
/// The connectivity mode to use.
|
||||
connectivity: Connectivity,
|
||||
/// Configured client timeout, in seconds.
|
||||
timeout: u64,
|
||||
timeout: Option<Duration>,
|
||||
}
|
||||
|
||||
impl RegistryClient {
|
||||
|
@ -170,7 +163,7 @@ impl RegistryClient {
|
|||
}
|
||||
|
||||
/// Return the timeout this client is configured with, in seconds.
|
||||
pub fn timeout(&self) -> u64 {
|
||||
pub fn timeout(&self) -> Option<Duration> {
|
||||
self.timeout
|
||||
}
|
||||
|
||||
|
|
|
@ -76,15 +76,16 @@ impl<'a, Context: BuildContext + Send + Sync> DistributionDatabase<'a, Context>
|
|||
/// Handle a specific `reqwest` error, and convert it to [`io::Error`].
|
||||
fn handle_response_errors(&self, err: reqwest::Error) -> io::Error {
|
||||
if err.is_timeout() {
|
||||
io::Error::new(
|
||||
io::ErrorKind::TimedOut,
|
||||
format!(
|
||||
"Failed to download distribution due to network timeout. Try increasing UV_HTTP_TIMEOUT (current value: {}s).", self.client.timeout()
|
||||
),
|
||||
)
|
||||
} else {
|
||||
io::Error::new(io::ErrorKind::Other, err)
|
||||
if let Some(timeout) = self.client.timeout() {
|
||||
return io::Error::new(
|
||||
io::ErrorKind::TimedOut,
|
||||
format!(
|
||||
"Failed to download distribution due to network timeout. Try increasing UV_HTTP_TIMEOUT (current value: {}s).", timeout.as_secs()
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
io::Error::new(io::ErrorKind::Other, err)
|
||||
}
|
||||
|
||||
/// Either fetch the wheel or fetch and build the source distribution
|
||||
|
|
|
@ -3,10 +3,12 @@
|
|||
//! Integration tests for the resolver. These tests rely on a live network connection, and hit
|
||||
//! `PyPI` directly.
|
||||
|
||||
use std::env;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::str::FromStr;
|
||||
use std::time::Duration;
|
||||
|
||||
use anyhow::Result;
|
||||
use anyhow::{Context, Result};
|
||||
use chrono::{DateTime, Utc};
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
|
@ -111,7 +113,34 @@ async fn resolve(
|
|||
markers: &'static MarkerEnvironment,
|
||||
tags: &Tags,
|
||||
) -> Result<ResolutionGraph> {
|
||||
let client = RegistryClientBuilder::new(Cache::temp()?).build();
|
||||
let mut registry_builder = RegistryClientBuilder::new(Cache::temp()?);
|
||||
|
||||
// Timeout options, matching https://doc.rust-lang.org/nightly/cargo/reference/config.html#httptimeout
|
||||
// `UV_REQUEST_TIMEOUT` is provided for backwards compatibility with v0.1.6
|
||||
let timeout_env_vars = ["UV_HTTP_TIMEOUT", "UV_REQUEST_TIMEOUT", "HTTP_TIMEOUT"];
|
||||
let timeout_or_error = timeout_env_vars.iter().find_map(|env_key| {
|
||||
if let Ok(env_value) = env::var(env_key) {
|
||||
let timeout = env_value.parse::<u64>().with_context(|| {
|
||||
format!(
|
||||
"Invalid value for {env_key}. \
|
||||
Expected integer number of seconds, got \"{env_value}\"."
|
||||
)
|
||||
});
|
||||
Some(timeout)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
|
||||
match timeout_or_error {
|
||||
Some(Ok(timeout)) => {
|
||||
registry_builder = registry_builder.timeout(Duration::from_secs(timeout));
|
||||
}
|
||||
Some(Err(err)) => return Err(err),
|
||||
None => {}
|
||||
}
|
||||
|
||||
let client = registry_builder.build();
|
||||
let flat_index = FlatIndex::default();
|
||||
let index = InMemoryIndex::default();
|
||||
let interpreter = Interpreter::artificial(Platform::current()?, markers.clone());
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue