Cache Safety, Errors, and Interruption
Errors preserve domain context
Crates define specific thiserror enums rather than one process-wide error.
For example, preparation distinguishes forbidden builds, forbidden binaries,
distribution failures, cyclic build dependencies, and failures copied from the
producer of a deduplicated request. Distribution errors carry the failing
artifact and derivation chain so CLI reporting can explain why it was needed.
The cache is shared, append-oriented evidence
Downloaded and built artifacts become immutable archive entries. uv prepares a
temporary directory, validates wheel records and hashes, then
Cache::persist
renames it into the archive. Other cache buckets can point at that immutable
entry. Readers never need to observe construction in progress.
In-process duplicate work has one producer
uv-once-map registers a key or waits for the registered producer. The producer
publishes either success or a cloneable error representation to all waiters.
This is cache stampede control, not just memoization after completion.
Cross-process mutation uses locks
The environment is locked for installation. Cache-cleaning operations take a stronger cache lock and use a timeout so administrative work does not deadlock forever behind active commands. RAII releases locks on error or cancellation.
Output durability has layers
Atomic file replacement protects individual metadata and cache entries. A target lock protects the environment’s multi-file transition from competing writers. A lockfile records the resolved intent. None alone provides all three guarantees.