git_workflow/pool/
lock.rs1use std::fs::{self, File};
4use std::path::{Path, PathBuf};
5use std::thread;
6use std::time::{Duration, Instant};
7
8use fs2::FileExt;
9
10use crate::error::{GwError, Result};
11
12const LOCK_TIMEOUT: Duration = Duration::from_secs(10);
14
15const LOCK_RETRY_INTERVAL: Duration = Duration::from_millis(50);
17
18pub struct PoolLock {
20 _file: File,
21 _path: PathBuf,
22}
23
24impl PoolLock {
25 pub fn acquire(pool_dir: &Path) -> Result<Self> {
29 Self::acquire_with_timeout(pool_dir, LOCK_TIMEOUT)
30 }
31
32 pub fn acquire_with_timeout(pool_dir: &Path, timeout: Duration) -> Result<Self> {
34 fs::create_dir_all(pool_dir)?;
35 let lock_path = pool_dir.join("pool.lock");
36 let file = File::create(&lock_path)?;
37
38 let start = Instant::now();
39 loop {
40 match file.try_lock_exclusive() {
41 Ok(()) => {
42 return Ok(Self {
43 _file: file,
44 _path: lock_path,
45 });
46 }
47 Err(_) if start.elapsed() < timeout => {
48 thread::sleep(LOCK_RETRY_INTERVAL);
49 }
50 Err(_) => {
51 return Err(GwError::PoolLockTimeout);
52 }
53 }
54 }
55 }
56}
57
58