Use atomic writes for the cache consistently (#546)

Ensure we're using atomic writes everywhere in our cache to avoid broken
cache records and error with parallel puffin actions
(https://github.com/astral-sh/puffin/pull/544#issuecomment-1838841581).

All json files that are written to the cache are written atomically and
the build wheels are written to temp dir and then moved atomically. I
didn't touch venv creation though, i don't think that's worth it since
python does not support atomic package installation through its design.
This commit is contained in:
konsti 2023-12-04 18:02:01 +01:00 committed by GitHub
parent e9c9e9718e
commit d5abd33813
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 69 additions and 36 deletions

View file

@ -24,7 +24,7 @@ use distribution_types::direct_url::{DirectArchiveUrl, DirectGitUrl};
use distribution_types::{GitSourceDist, Identifier, RemoteSource, SourceDist};
use install_wheel_rs::read_dist_info;
use platform_tags::Tags;
use puffin_cache::{digest, CacheBucket, CacheEntry, CanonicalUrl, WheelCache};
use puffin_cache::{digest, write_atomic, CacheBucket, CacheEntry, CanonicalUrl, WheelCache};
use puffin_client::{CachedClient, CachedClientError, DataWithCachePolicy};
use puffin_git::{Fetch, GitSource};
use puffin_normalize::PackageName;
@ -351,7 +351,7 @@ impl<'a, T: BuildContext> SourceDistCachedBuilder<'a, T> {
cached
.data
.insert(wheel_filename.clone(), cached_data.clone());
fs::write(cache_entry.path(), serde_json::to_vec(&cached)?).await?;
write_atomic(cache_entry.path(), serde_json::to_vec(&cached)?).await?;
};
Ok(BuiltWheelMetadata::from_cached(
@ -430,9 +430,9 @@ impl<'a, T: BuildContext> SourceDistCachedBuilder<'a, T> {
metadata: metadata.clone(),
},
);
let cached = serde_json::to_vec(&metadatas)?;
fs::create_dir_all(&cache_entry.dir).await?;
fs::write(cache_entry.path(), cached).await?;
let data = serde_json::to_vec(&metadatas)?;
write_atomic(cache_entry.path(), data).await?;
if let Some(task) = task {
if let Some(reporter) = self.reporter.as_ref() {