use std::sync::Arc;
use std::sync::Mutex;
use std::time::Duration;
use crate::network::Backoff;
const EXHAUSTED_BACKOFF_DELAY: Duration = Duration::from_millis(500);
#[derive(Clone)]
pub(crate) struct BackoffConsumer {
pub(crate) inner: Arc<Mutex<Option<Backoff>>>,
}
impl BackoffConsumer {
pub(crate) fn next_delay(&self) -> Option<Duration> {
let mut guard = self.inner.lock().unwrap();
let backoff = guard.as_mut()?;
Some(backoff.next().unwrap_or(EXHAUSTED_BACKOFF_DELAY))
}
}
#[cfg(test)]
mod tests {
use std::time::Duration;
use crate::network::Backoff;
use crate::replication::backoff_state::BackoffState;
fn constant_200ms_backoff() -> Backoff {
Backoff::new(std::iter::repeat(Duration::from_millis(200)))
}
#[test]
fn samples_delay_only_when_enabled() {
let mut state = BackoffState::new();
let consumer = state.consumer();
assert_eq!(consumer.next_delay(), None, "disabled: no delay");
state.on_error(100);
state.reconcile(constant_200ms_backoff);
assert_eq!(
consumer.next_delay(),
Some(Duration::from_millis(200)),
"enabled: yields configured delay"
);
state.on_success();
assert_eq!(consumer.next_delay(), None, "after success: no delay");
}
}