Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disallow bad retry delay/jitter combination #2

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/example.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ fn example() -> RedlockResult<()> {
"redis2.example.com",
"redis3.example.com"],
retry_count: 10,
retry_delay: time::Duration::from_millis(400),
retry_delay: time::Duration::from_millis(401),
retry_jitter: 400,
drift_factor: 0.01,
})?;
Expand Down
1 change: 1 addition & 0 deletions src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ quick_error!{
TimeError(err: time::SystemTimeError) { from(err: time::SystemTimeError) -> (err) }
NoServerError { description("Redlock must be initialized with at least one redis server") }
TimeoutError { description("Redlock request timeout") }
DelayJitterError { description("Retry jitter must be smaller than retry delay") }
LockExpired { description("The lock has already expired") }
UnableToLock { description("Unable to lock the resource") }
UnableToUnlock { description("Unable to unlock the resource") }
Expand Down
25 changes: 14 additions & 11 deletions src/redlock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ pub struct Config<T>
pub addrs: Vec<T>,
pub retry_count: u32,
pub retry_delay: Duration,
pub retry_jitter: u32,
pub retry_jitter: u64,
pub drift_factor: f32,
}

Expand All @@ -55,7 +55,7 @@ impl Default for Config<&'static str> {
Config {
addrs: vec!["redis://127.0.0.1"],
retry_count: 10,
retry_delay: Duration::from_millis(400),
retry_delay: Duration::from_millis(401),
retry_jitter: 400,
drift_factor: 0.01,
}
Expand All @@ -67,7 +67,7 @@ pub struct Redlock {
clients: Vec<redis::Client>,
retry_count: u32,
retry_delay: Duration,
retry_jitter: u32,
retry_jitter: u64,
drift_factor: f32,
quorum: usize,
}
Expand All @@ -78,6 +78,9 @@ impl Redlock {
if config.addrs.is_empty() {
return Err(RedlockError::NoServerError);
}
if Duration::from_millis(config.retry_jitter) >= config.retry_delay {
return Err(RedlockError::DelayJitterError);
}
let mut clients = Vec::with_capacity(config.addrs.len());
for addr in config.addrs {
clients.push(redis::Client::open(addr)?)
Expand Down Expand Up @@ -231,11 +234,11 @@ impl Redlock {
}

fn get_retry_timeout(&self) -> Duration {
let jitter = self.retry_jitter as i32 * thread_rng().gen_range(-1, 1);
if jitter >= 0 {
self.retry_delay.add(Duration::from_millis(jitter as u64))
let jitter = thread_rng().gen_range(-1, 1);
if jitter == -1 {
self.retry_delay.sub(Duration::from_millis(self.retry_jitter))
} else {
self.retry_delay.sub(Duration::from_millis(-jitter as u64))
self.retry_delay.add(Duration::from_millis(self.retry_jitter))
}
}
}
Expand Down Expand Up @@ -288,7 +291,7 @@ mod tests {
static ref REDLOCK: Redlock = Redlock::new::<&str>(Config {
addrs: vec!["redis://127.0.0.1"],
retry_count: 10,
retry_delay: Duration::from_millis(400),
retry_delay: Duration::from_millis(401),
retry_jitter: 400,
drift_factor: 0.01,
}).unwrap();
Expand All @@ -301,7 +304,7 @@ mod tests {
let default_config = Config::default();
assert_eq!(default_config.addrs, vec!["redis://127.0.0.1"]);
assert_eq!(default_config.retry_count, 10);
assert_eq!(default_config.retry_delay, Duration::from_millis(400));
assert_eq!(default_config.retry_delay, Duration::from_millis(401));
assert_eq!(default_config.retry_jitter, 400);
assert_eq!(default_config.drift_factor, 0.01);
}
Expand All @@ -312,7 +315,7 @@ mod tests {
Redlock::new::<&str>(Config {
addrs: vec![],
retry_count: 10,
retry_delay: Duration::from_millis(400),
retry_delay: Duration::from_millis(401),
retry_jitter: 400,
drift_factor: 0.01,
})
Expand All @@ -324,7 +327,7 @@ mod tests {
let redlock = Redlock::new(Config::default()).unwrap();
assert_eq!(redlock.clients.len(), 1);
assert_eq!(redlock.retry_count, 10);
assert_eq!(redlock.retry_delay, Duration::from_millis(400));
assert_eq!(redlock.retry_delay, Duration::from_millis(401));
}

#[test]
Expand Down