From e9953165d3560aaa6e474e4f0977c53609ecf367 Mon Sep 17 00:00:00 2001 From: Roman Timushev Date: Thu, 27 Jun 2024 14:41:07 +0200 Subject: [PATCH] Cache lock improvements (#140) 1. Exponential backoff makes protofetch sometimes take too long to run. 2. It makes sense to initialize signal handlers to make sure the locks are removed when protofetch is killed. --- Cargo.lock | 53 ++++++++++++++++++++++++++++++++++++++++-------- Cargo.toml | 3 ++- src/git/cache.rs | 29 +++++++++++++++----------- 3 files changed, 64 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 99513b1..253c8dc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -229,6 +229,19 @@ dependencies = [ "typenum", ] +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown", + "lock_api", + "once_cell", + "parking_lot_core", +] + [[package]] name = "der" version = "0.7.8" @@ -387,9 +400,9 @@ dependencies = [ [[package]] name = "gix-features" -version = "0.38.1" +version = "0.38.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db4254037d20a247a0367aa79333750146a369719f0c6617fec4f5752cc62b37" +checksum = "ac7045ac9fe5f9c727f38799d002a7ed3583cd777e3322a7c4b43e3cf437dc69" dependencies = [ "gix-hash", "gix-trace", @@ -399,10 +412,11 @@ dependencies = [ [[package]] name = "gix-fs" -version = "0.10.2" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2184c40e7910529677831c8b481acf788ffd92427ed21fad65b6aa637e631b8" +checksum = "c3338ff92a2164f5209f185ec0cd316f571a72676bb01d27e22f2867ba69f77a" dependencies = [ + "fastrand", "gix-features", "gix-utils", ] @@ -419,9 +433,9 @@ dependencies = [ [[package]] name = "gix-lock" -version = "13.1.1" +version = "14.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7c359f81f01b8352063319bcb39789b7ea0887b406406381106e38c4a34d049" +checksum = "e3bc7fe297f1f4614774989c00ec8b1add59571dc9b024b4c00acb7dedd4e19d" dependencies = [ "gix-tempfile", "gix-utils", @@ -430,14 +444,17 @@ dependencies = [ [[package]] name = "gix-tempfile" -version = "13.1.1" +version = "14.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a761d76594f4443b675e85928e4902dec333273836bd386906f01e7e346a0d11" +checksum = "d3b0e276cd08eb2a22e9f286a4f13a222a01be2defafa8621367515375644b99" dependencies = [ + "dashmap", "gix-fs", "libc", "once_cell", "parking_lot", + "signal-hook", + "signal-hook-registry", "tempfile", ] @@ -885,6 +902,7 @@ dependencies = [ "env_logger", "git2", "gix-lock", + "gix-tempfile", "home", "log", "pretty_assertions", @@ -1053,6 +1071,25 @@ dependencies = [ "digest", ] +[[package]] +name = "signal-hook" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +dependencies = [ + "libc", +] + [[package]] name = "signature" version = "2.1.0" diff --git a/Cargo.toml b/Cargo.toml index cfc23ff..9d9911c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,8 @@ clap = { version = "4.4.7", features = ["derive"] } config = { version = "0.13.3", default-features = false, features = ["toml"] } env_logger = { version = "0.10.0", default-features = false, features = ["auto-color"] } git2 = "0.18.1" -gix-lock = "13.1.1" +gix-lock = { version = "14.0.0" } +gix-tempfile = { version = "14.0.0", features = ["signals"] } home = "0.5.5" log = "0.4.20" regex-lite = "0.1.5" diff --git a/src/git/cache.rs b/src/git/cache.rs index ec98075..5756e2b 100644 --- a/src/git/cache.rs +++ b/src/git/cache.rs @@ -1,6 +1,6 @@ use std::{ path::{Path, PathBuf}, - time::Duration, + time::{Duration, Instant}, }; use git2::{ @@ -56,6 +56,7 @@ impl ProtofetchGitCache { std::fs::create_dir_all(&location)?; } + gix_lock::tempfile::signal::setup(Default::default()); let lock = Self::acquire_lock(&location)?; let worktrees = location.join(WORKTREES_DIR); @@ -98,17 +99,21 @@ impl ProtofetchGitCache { "Acquiring a lock on the cache location: {}", location.display() ); - match Marker::acquire_to_hold_resource(location, Fail::Immediately, None) { - Ok(lock) => Ok(lock), - Err(_) => { - info!("Failed to acquire a lock on the cache location, retrying"); - let lock = Marker::acquire_to_hold_resource( - location, - Fail::AfterDurationWithBackoff(Duration::from_secs(300)), - None, - )?; - info!("Acquired a lock on the cache location"); - Ok(lock) + let start = Instant::now(); + loop { + match Marker::acquire_to_hold_resource(location, Fail::Immediately, None) { + Ok(lock) => { + info!("Acquired a lock on the cache location"); + return Ok(lock); + } + Err(error) => { + if start.elapsed() < Duration::from_secs(300) { + debug!("Failed to acquire a lock on the cache location, retrying"); + std::thread::sleep(Duration::from_secs(1)); + } else { + return Err(error.into()); + } + } } } }