From ca118adbfe922a03fc922271f8712dc24a29ec35 Mon Sep 17 00:00:00 2001 From: Alejandro Cabeza Romero Date: Thu, 14 May 2026 13:50:20 +0200 Subject: [PATCH] Add shared cache with file lock to prevent redundant parallel downloads. --- rust/Cargo.lock | 14 +++++++++- rust/Cargo.toml | 1 + .../Cargo.toml | 3 ++- .../src/lib.rs | 26 ++++++++++++++++--- 4 files changed, 38 insertions(+), 6 deletions(-) diff --git a/rust/Cargo.lock b/rust/Cargo.lock index edc9d92..597742d 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -79,6 +79,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "fd-lock" +version = "4.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce92ff622d6dadf7349484f42c93271a0d49b7cc4d466a936405bacbe10aa78" +dependencies = [ + "cfg-if", + "rustix", "windows-sys 0.52.0", ] @@ -177,6 +188,7 @@ name = "logos-blockchain-circuits-build" version = "0.5.0" dependencies = [ "dirs", + "fd-lock", "flate2", "tar", "ureq", @@ -329,7 +341,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 68d5c41..ef61e69 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -32,6 +32,7 @@ lbc-types = { default-features = false, package = "logos-blockchain-circuits-typ # External dirs = "^6" +fd-lock = "^4" flate2 = "^1.1" libc = "^0.2" tar = "^0.4" diff --git a/rust/logos-blockchain-circuits-build/Cargo.toml b/rust/logos-blockchain-circuits-build/Cargo.toml index bd03025..b0fd891 100644 --- a/rust/logos-blockchain-circuits-build/Cargo.toml +++ b/rust/logos-blockchain-circuits-build/Cargo.toml @@ -10,13 +10,14 @@ repository.workspace = true version.workspace = true [features] -prebuilt = ["dep:dirs", "dep:flate2", "dep:tar", "dep:ureq"] +prebuilt = ["dep:dirs", "dep:fd-lock", "dep:flate2", "dep:tar", "dep:ureq"] [lints] workspace = true [dependencies] dirs = { workspace = true, optional = true } +fd-lock = { workspace = true, optional = true } flate2 = { workspace = true, optional = true } tar = { workspace = true, optional = true } ureq = { workspace = true, optional = true } diff --git a/rust/logos-blockchain-circuits-build/src/lib.rs b/rust/logos-blockchain-circuits-build/src/lib.rs index 205dfd7..6b579ef 100644 --- a/rust/logos-blockchain-circuits-build/src/lib.rs +++ b/rust/logos-blockchain-circuits-build/src/lib.rs @@ -59,7 +59,18 @@ mod prebuilt { unpacked_library_directory } - fn cache_dir() -> PathBuf { + /// Produce a lockfile for the given directory + fn get_lockfile(directory: &Path) -> fd_lock::RwLock { + let file = std::fs::OpenOptions::new() + .create(true) + .truncate(false) + .write(true) + .open(directory.join(".lock")) + .expect("Failed to open cache lock file."); + fd_lock::RwLock::new(file) + } + + fn get_cache_dir() -> PathBuf { dirs::cache_dir() .expect("Could not determine the cache directory for this platform.") .join("logos") @@ -71,13 +82,22 @@ mod prebuilt { let os = std::env::var("CARGO_CFG_TARGET_OS").unwrap(); let arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap(); - let cache = cache_dir(); + let cache = get_cache_dir(); // The tarball unpacks to a top-level `{artifact_name}/` dir, so the circuit lives at // `cache/{artifact_name}/{circuit_name}/`. let circuit_dir = cache .join(build_artifact_name(version, &os, &arch)) .join(circuit_name); + std::fs::create_dir_all(&cache).expect("Failed to create the cache directory."); + + // Since the circuits' libraries are all contained in the same single artifact, each crate + // will try to download the same circuits. + // To avoid redundant downloads, we use a lock to ensure that only one process fetches the + // circuits while the others wait for it to complete and then re-check the cache. + let mut lock = get_lockfile(&cache); + let _guard = lock.write().expect("Failed to acquire cache lock."); + if circuit_dir.is_dir() { println!( "Found a cached {circuit_name} library at {}, reusing.", @@ -86,8 +106,6 @@ mod prebuilt { return circuit_dir; } - std::fs::create_dir_all(&cache).expect("Failed to create cache directory."); - println!( "No cached download found, downloading {circuit_name} v{version} for {os}-{arch}..." );