Skip to content

Commit

Permalink
Use more robust cache locking (#150)
Browse files Browse the repository at this point in the history
The lock created by `gix-lock` is not cleared when the process is
killed. This, however, seems to happen quite often when protofetch is
used in a cargo build script and a project is opened in VSCode with
rust-analyzer.

The lock implementation in this PR is resilient to such issues.
  • Loading branch information
rtimush authored Aug 16, 2024
1 parent e5a4e8e commit 3881e1a
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 213 deletions.
193 changes: 11 additions & 182 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 2 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "protofetch"
version = "0.1.7"
edition = "2021"
rust-version = "1.74"
rust-version = "1.75"
license = "Apache-2.0"
description = "A source dependency management tool for Protobuf."
homepage = "https://github.com/coralogix/protofetch"
Expand All @@ -21,9 +21,8 @@ anyhow = "1.0.86"
clap = { version = "4.5.9", features = ["derive"] }
config = { version = "0.14.0", default-features = false, features = ["toml"] }
env_logger = { version = "0.11.3", default-features = false, features = ["auto-color"] }
fs4 = "0.9.1"
git2 = ">=0.18.0, <0.20.0"
gix-lock = { version = "14.0.0" }
gix-tempfile = { version = "14.0.0", features = ["signals"] }
home = "0.5.9"
log = "0.4.22"
regex-lite = "0.1.6"
Expand Down
2 changes: 1 addition & 1 deletion rust-toolchain.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
# The default profile includes rustc, rust-std, cargo, rust-docs, rustfmt and clippy.
# https://rust-lang.github.io/rustup/concepts/profiles.html
profile = "default"
channel = "1.79.0"
channel = "1.80.1"
39 changes: 39 additions & 0 deletions src/flock.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use std::{
fs::File,
path::Path,
time::{Duration, Instant},
};

use fs4::fs_std::FileExt;
use log::debug;
use thiserror::Error;

pub struct FileLock {
_file: File,
}

#[derive(Error, Debug)]
#[error(transparent)]
pub struct Error(#[from] std::io::Error);

impl FileLock {
pub fn new(path: &Path) -> Result<Self, Error> {
let file = File::create(path)?;
let start = Instant::now();
loop {
match file.try_lock_exclusive() {
Ok(_) => {
return Ok(Self { _file: file });
}
Err(error)
if error.raw_os_error() == fs4::lock_contended_error().raw_os_error()
&& start.elapsed().as_secs() < 300 =>
{
debug!("Failed to acquire a lock on {}, retrying", path.display());
std::thread::sleep(Duration::from_secs(1));
}
Err(error) => return Err(error.into()),
}
}
}
}
Loading

0 comments on commit 3881e1a

Please sign in to comment.