diff options
Diffstat (limited to 'vendor/gix-lock/src')
-rw-r--r-- | vendor/gix-lock/src/acquire.rs | 9 | ||||
-rw-r--r-- | vendor/gix-lock/src/backoff.rs | 142 | ||||
-rw-r--r-- | vendor/gix-lock/src/file.rs | 2 | ||||
-rw-r--r-- | vendor/gix-lock/src/lib.rs | 4 |
4 files changed, 5 insertions, 152 deletions
diff --git a/vendor/gix-lock/src/acquire.rs b/vendor/gix-lock/src/acquire.rs index 93655a7da..c94fd110a 100644 --- a/vendor/gix-lock/src/acquire.rs +++ b/vendor/gix-lock/src/acquire.rs @@ -9,21 +9,16 @@ use gix_tempfile::{AutoRemove, ContainingDirectory}; use crate::{backoff, File, Marker, DOT_LOCK_SUFFIX}; /// Describe what to do if a lock cannot be obtained as it's already held elsewhere. -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] +#[derive(Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] pub enum Fail { /// Fail after the first unsuccessful attempt of obtaining a lock. + #[default] Immediately, /// Retry after failure with exponentially longer sleep times to block the current thread. /// Fail once the given duration is exceeded, similar to [Fail::Immediately] AfterDurationWithBackoff(Duration), } -impl Default for Fail { - fn default() -> Self { - Fail::Immediately - } -} - impl fmt::Display for Fail { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { diff --git a/vendor/gix-lock/src/backoff.rs b/vendor/gix-lock/src/backoff.rs deleted file mode 100644 index f1c3559a6..000000000 --- a/vendor/gix-lock/src/backoff.rs +++ /dev/null @@ -1,142 +0,0 @@ -use std::time::Duration; - -fn randomize(backoff_ms: usize) -> usize { - let new_value = (fastrand::usize(750..=1250) * backoff_ms) / 1000; - if new_value == 0 { - backoff_ms - } else { - new_value - } -} - -/// A utility to calculate steps for exponential backoff similar to how it's done in `git`. -pub struct Exponential<Fn> { - multiplier: usize, - max_multiplier: usize, - exponent: usize, - transform: Fn, -} - -impl Default for Exponential<fn(usize) -> usize> { - fn default() -> Self { - Exponential { - multiplier: 1, - max_multiplier: 1000, - exponent: 1, - transform: std::convert::identity, - } - } -} - -impl Exponential<fn(usize) -> usize> { - /// Create a new exponential backoff iterator that backs off in randomized, ever increasing steps. - pub fn default_with_random() -> Self { - Exponential { - multiplier: 1, - max_multiplier: 1000, - exponent: 1, - transform: randomize, - } - } -} - -impl<Transform> Exponential<Transform> -where - Transform: Fn(usize) -> usize, -{ - /// Return an iterator that yields `Duration` instances to sleep on until `time` is depleted. - pub fn until_no_remaining(&mut self, time: Duration) -> impl Iterator<Item = Duration> + '_ { - let mut elapsed = Duration::default(); - let mut stop_next_iteration = false; - self.take_while(move |d| { - if stop_next_iteration { - false - } else { - elapsed += *d; - if elapsed > time { - stop_next_iteration = true; - } - true - } - }) - } -} - -impl<Transform> Iterator for Exponential<Transform> -where - Transform: Fn(usize) -> usize, -{ - type Item = Duration; - - fn next(&mut self) -> Option<Self::Item> { - let wait = Duration::from_millis((self.transform)(self.multiplier) as u64); - - self.multiplier += 2 * self.exponent + 1; - if self.multiplier > self.max_multiplier { - self.multiplier = self.max_multiplier; - } else { - self.exponent += 1; - } - Some(wait) - } -} - -#[cfg(test)] -mod tests { - use std::convert::TryInto; - - use super::*; - - const EXPECTED_TILL_SECOND: &[usize] = &[ - 1usize, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324, 361, 400, 441, 484, 529, - 576, 625, 676, 729, 784, 841, 900, 961, 1000, 1000, - ]; - - #[test] - fn random_exponential_produces_values_in_the_correct_range() { - let mut num_identities = 0; - for (actual, expected) in Exponential::default_with_random().zip(EXPECTED_TILL_SECOND) { - let actual: usize = actual.as_millis().try_into().unwrap(); - if actual == *expected { - num_identities += 1; - } - assert!( - actual * 1000 >= (expected - 1) * 750, - "value too small: {actual} < {expected}" - ); - assert!( - actual * 1000 <= (expected + 1) * 1250, - "value too big: {actual} > {expected}" - ); - } - assert!( - num_identities < EXPECTED_TILL_SECOND.len(), - "too many untransformed values: {num_identities}" - ); - } - - #[test] - fn how_many_iterations_for_a_second_of_waittime() { - let max = Duration::from_millis(1000); - assert_eq!(Exponential::default().until_no_remaining(max).count(), 14); - assert_eq!( - Exponential::default() - .until_no_remaining(max) - .reduce(|acc, n| acc + n) - .unwrap(), - Duration::from_millis(1015), - "a little overshoot" - ); - } - - #[test] - fn output_with_default_settings() { - assert_eq!( - Exponential::default().take(33).collect::<Vec<_>>(), - EXPECTED_TILL_SECOND - .iter() - .map(|n| Duration::from_millis(*n as u64)) - .collect::<Vec<_>>() - ); - } -} diff --git a/vendor/gix-lock/src/file.rs b/vendor/gix-lock/src/file.rs index ad9a6db06..24ec98f13 100644 --- a/vendor/gix-lock/src/file.rs +++ b/vendor/gix-lock/src/file.rs @@ -17,7 +17,7 @@ impl File { self.inner.with_mut(|tf| f(tf.as_file_mut())).and_then(|res| res) } /// Close the lock file to prevent further writes and to save system resources. - /// A call to [Marker::commit()] is allowed on the [`Marker`] to write changes back to the resource. + /// A call to [`Marker::commit()`] is allowed on the [`Marker`] to write changes back to the resource. pub fn close(self) -> std::io::Result<Marker> { Ok(Marker { inner: self.inner.close()?, diff --git a/vendor/gix-lock/src/lib.rs b/vendor/gix-lock/src/lib.rs index 882e15492..3f131f7a6 100644 --- a/vendor/gix-lock/src/lib.rs +++ b/vendor/gix-lock/src/lib.rs @@ -24,8 +24,8 @@ const DOT_LOCK_SUFFIX: &str = ".lock"; /// pub mod acquire; -/// -pub mod backoff; + +pub use gix_utils::backoff; /// pub mod commit; |