Skip to content

Commit ada1acb

Browse files
authored
Make cache errors non-fatal in Planner::build (#12281)
Same basic approach as #11105, including a cache version bump. Fixes #12274
1 parent faf16c1 commit ada1acb

File tree

5 files changed

+194
-120
lines changed

5 files changed

+194
-120
lines changed

crates/uv-cache/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1000,7 +1000,7 @@ impl CacheBucket {
10001000
match self {
10011001
// Note that when bumping this, you'll also need to bump it
10021002
// in `crates/uv/tests/it/cache_prune.rs`.
1003-
Self::SourceDistributions => "sdists-v8",
1003+
Self::SourceDistributions => "sdists-v9",
10041004
Self::FlatIndex => "flat-index-v2",
10051005
Self::Git => "git-v0",
10061006
Self::Interpreter => "interpreter-v4",

crates/uv-installer/src/plan.rs

Lines changed: 124 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ impl<'a> Planner<'a> {
9797
[] => {}
9898
[installed] => {
9999
let source = RequirementSource::from(dist);
100-
match RequirementSatisfaction::check(installed, &source)? {
100+
match RequirementSatisfaction::check(installed, &source) {
101101
RequirementSatisfaction::Mismatch => {
102102
debug!("Requirement installed, but mismatched:\n Installed: {installed:?}\n Requested: {source:?}");
103103
}
@@ -108,6 +108,9 @@ impl<'a> Planner<'a> {
108108
RequirementSatisfaction::OutOfDate => {
109109
debug!("Requirement installed, but not fresh: {installed}");
110110
}
111+
RequirementSatisfaction::CacheInvalid => {
112+
// Already logged
113+
}
111114
}
112115
reinstalls.push(installed.clone());
113116
}
@@ -180,24 +183,31 @@ impl<'a> Planner<'a> {
180183
.entry(format!("{}.http", wheel.filename.cache_key()));
181184

182185
// Read the HTTP pointer.
183-
if let Some(pointer) = HttpArchivePointer::read_from(&cache_entry)? {
184-
let cache_info = pointer.to_cache_info();
185-
let archive = pointer.into_archive();
186-
if archive.satisfies(hasher.get(dist.as_ref())) {
187-
let cached_dist = CachedDirectUrlDist {
188-
filename: wheel.filename.clone(),
189-
url: VerbatimParsedUrl {
190-
parsed_url: wheel.parsed_url(),
191-
verbatim: wheel.url.clone(),
192-
},
193-
hashes: archive.hashes,
194-
cache_info,
195-
path: cache.archive(&archive.id),
196-
};
197-
198-
debug!("URL wheel requirement already cached: {cached_dist}");
199-
cached.push(CachedDist::Url(cached_dist));
200-
continue;
186+
match HttpArchivePointer::read_from(&cache_entry) {
187+
Ok(Some(pointer)) => {
188+
let cache_info = pointer.to_cache_info();
189+
let archive = pointer.into_archive();
190+
if archive.satisfies(hasher.get(dist.as_ref())) {
191+
let cached_dist = CachedDirectUrlDist {
192+
filename: wheel.filename.clone(),
193+
url: VerbatimParsedUrl {
194+
parsed_url: wheel.parsed_url(),
195+
verbatim: wheel.url.clone(),
196+
},
197+
hashes: archive.hashes,
198+
cache_info,
199+
path: cache.archive(&archive.id),
200+
};
201+
202+
debug!("URL wheel requirement already cached: {cached_dist}");
203+
cached.push(CachedDist::Url(cached_dist));
204+
continue;
205+
}
206+
debug!("Cached URL wheel requirement does not match expected hash policy for: {wheel}");
207+
}
208+
Ok(None) => {}
209+
Err(err) => {
210+
debug!("Failed to deserialize cached URL wheel requirement for: {wheel} ({err})");
201211
}
202212
}
203213
}
@@ -230,28 +240,41 @@ impl<'a> Planner<'a> {
230240
)
231241
.entry(format!("{}.rev", wheel.filename.cache_key()));
232242

233-
if let Some(pointer) = LocalArchivePointer::read_from(&cache_entry)? {
234-
let timestamp = Timestamp::from_path(&wheel.install_path)?;
235-
if pointer.is_up_to_date(timestamp) {
236-
let cache_info = pointer.to_cache_info();
237-
let archive = pointer.into_archive();
238-
if archive.satisfies(hasher.get(dist.as_ref())) {
239-
let cached_dist = CachedDirectUrlDist {
240-
filename: wheel.filename.clone(),
241-
url: VerbatimParsedUrl {
242-
parsed_url: wheel.parsed_url(),
243-
verbatim: wheel.url.clone(),
244-
},
245-
hashes: archive.hashes,
246-
cache_info,
247-
path: cache.archive(&archive.id),
248-
};
249-
250-
debug!("Path wheel requirement already cached: {cached_dist}");
251-
cached.push(CachedDist::Url(cached_dist));
252-
continue;
243+
match LocalArchivePointer::read_from(&cache_entry) {
244+
Ok(Some(pointer)) => {
245+
match Timestamp::from_path(&wheel.install_path) {
246+
Ok(timestamp) => {
247+
if pointer.is_up_to_date(timestamp) {
248+
let cache_info = pointer.to_cache_info();
249+
let archive = pointer.into_archive();
250+
if archive.satisfies(hasher.get(dist.as_ref())) {
251+
let cached_dist = CachedDirectUrlDist {
252+
filename: wheel.filename.clone(),
253+
url: VerbatimParsedUrl {
254+
parsed_url: wheel.parsed_url(),
255+
verbatim: wheel.url.clone(),
256+
},
257+
hashes: archive.hashes,
258+
cache_info,
259+
path: cache.archive(&archive.id),
260+
};
261+
262+
debug!("Path wheel requirement already cached: {cached_dist}");
263+
cached.push(CachedDist::Url(cached_dist));
264+
continue;
265+
}
266+
debug!("Cached path wheel requirement does not match expected hash policy for: {wheel}");
267+
}
268+
}
269+
Err(err) => {
270+
debug!("Failed to get timestamp for wheel {wheel} ({err})");
271+
}
253272
}
254273
}
274+
Ok(None) => {}
275+
Err(err) => {
276+
debug!("Failed to deserialize cached path wheel requirement for: {wheel} ({err})");
277+
}
255278
}
256279
}
257280
Dist::Source(SourceDist::Registry(sdist)) => {
@@ -281,19 +304,27 @@ impl<'a> Planner<'a> {
281304
Dist::Source(SourceDist::DirectUrl(sdist)) => {
282305
// Find the most-compatible wheel from the cache, since we don't know
283306
// the filename in advance.
284-
if let Some(wheel) = built_index.url(sdist)? {
285-
if wheel.filename.name == sdist.name {
286-
let cached_dist = wheel.into_url_dist(sdist);
287-
debug!("URL source requirement already cached: {cached_dist}");
288-
cached.push(CachedDist::Url(cached_dist));
289-
continue;
290-
}
307+
match built_index.url(sdist) {
308+
Ok(Some(wheel)) => {
309+
if wheel.filename.name == sdist.name {
310+
let cached_dist = wheel.into_url_dist(sdist);
311+
debug!("URL source requirement already cached: {cached_dist}");
312+
cached.push(CachedDist::Url(cached_dist));
313+
continue;
314+
}
291315

292-
warn!(
293-
"Cached wheel filename does not match requested distribution for: `{}` (found: `{}`)",
294-
sdist,
295-
wheel.filename
296-
);
316+
warn!(
317+
"Cached wheel filename does not match requested distribution for: `{}` (found: `{}`)",
318+
sdist,
319+
wheel.filename
320+
);
321+
}
322+
Ok(None) => {}
323+
Err(err) => {
324+
debug!(
325+
"Failed to deserialize cached wheel filename for: {sdist} ({err})"
326+
);
327+
}
297328
}
298329
}
299330
Dist::Source(SourceDist::Git(sdist)) => {
@@ -322,19 +353,27 @@ impl<'a> Planner<'a> {
322353

323354
// Find the most-compatible wheel from the cache, since we don't know
324355
// the filename in advance.
325-
if let Some(wheel) = built_index.path(sdist)? {
326-
if wheel.filename.name == sdist.name {
327-
let cached_dist = wheel.into_path_dist(sdist);
328-
debug!("Path source requirement already cached: {cached_dist}");
329-
cached.push(CachedDist::Url(cached_dist));
330-
continue;
331-
}
356+
match built_index.path(sdist) {
357+
Ok(Some(wheel)) => {
358+
if wheel.filename.name == sdist.name {
359+
let cached_dist = wheel.into_path_dist(sdist);
360+
debug!("Path source requirement already cached: {cached_dist}");
361+
cached.push(CachedDist::Url(cached_dist));
362+
continue;
363+
}
332364

333-
warn!(
334-
"Cached wheel filename does not match requested distribution for: `{}` (found: `{}`)",
335-
sdist,
336-
wheel.filename
337-
);
365+
warn!(
366+
"Cached wheel filename does not match requested distribution for: `{}` (found: `{}`)",
367+
sdist,
368+
wheel.filename
369+
);
370+
}
371+
Ok(None) => {}
372+
Err(err) => {
373+
debug!(
374+
"Failed to deserialize cached wheel filename for: {sdist} ({err})"
375+
);
376+
}
338377
}
339378
}
340379
Dist::Source(SourceDist::Directory(sdist)) => {
@@ -345,19 +384,29 @@ impl<'a> Planner<'a> {
345384

346385
// Find the most-compatible wheel from the cache, since we don't know
347386
// the filename in advance.
348-
if let Some(wheel) = built_index.directory(sdist)? {
349-
if wheel.filename.name == sdist.name {
350-
let cached_dist = wheel.into_directory_dist(sdist);
351-
debug!("Directory source requirement already cached: {cached_dist}");
352-
cached.push(CachedDist::Url(cached_dist));
353-
continue;
354-
}
387+
match built_index.directory(sdist) {
388+
Ok(Some(wheel)) => {
389+
if wheel.filename.name == sdist.name {
390+
let cached_dist = wheel.into_directory_dist(sdist);
391+
debug!(
392+
"Directory source requirement already cached: {cached_dist}"
393+
);
394+
cached.push(CachedDist::Url(cached_dist));
395+
continue;
396+
}
355397

356-
warn!(
357-
"Cached wheel filename does not match requested distribution for: `{}` (found: `{}`)",
358-
sdist,
359-
wheel.filename
360-
);
398+
warn!(
399+
"Cached wheel filename does not match requested distribution for: `{}` (found: `{}`)",
400+
sdist,
401+
wheel.filename
402+
);
403+
}
404+
Ok(None) => {}
405+
Err(err) => {
406+
debug!(
407+
"Failed to deserialize cached wheel filename for: {sdist} ({err})"
408+
);
409+
}
361410
}
362411
}
363412
}

0 commit comments

Comments
 (0)