use std::{
thread,
time::{Duration, SystemTime},
};
#[inline]
pub fn eventually<F>(predicate: F, error_msg: &str)
where
F: Fn() -> bool,
{
let start = SystemTime::now();
let mut tick = Duration::from_millis(5); let timeout = Duration::from_secs(10); let max_tick = Duration::from_millis(100);
loop {
let elapsed = start.elapsed();
if elapsed.is_err() {
panic!("System time error");
}
let elapsed = elapsed.unwrap();
if elapsed > timeout {
panic!("{}", error_msg);
}
if predicate() {
return;
}
thread::sleep(tick);
tick = std::cmp::min(tick * 2, max_tick);
}
}
#[inline]
pub async fn eventually_async<F, Fut>(mut predicate: F, error_msg: &str)
where
F: FnMut() -> Fut,
Fut: std::future::Future<Output = bool>,
{
let start = SystemTime::now();
let tick = Duration::from_millis(10);
let timeout = Duration::from_secs(3);
loop {
let elapsed = start.elapsed();
if elapsed.is_err() {
panic!("System time error");
}
let elapsed = elapsed.unwrap();
if elapsed > timeout {
panic!("{}", error_msg);
}
if predicate().await {
return;
}
tokio::time::sleep(tick).await;
}
}