use std::time::{Duration, Instant};
pub struct WaitProgress {
label: String,
method: String,
prefix: String,
timeout: Duration,
heartbeat: Duration,
start: Instant,
last_logged: Instant,
checks: u32,
}
impl WaitProgress {
pub fn new(label: impl Into<String>, method: impl Into<String>, timeout: Duration) -> Self {
let start = Instant::now();
Self {
label: label.into(),
method: method.into(),
prefix: " ".to_string(),
timeout,
heartbeat: Duration::from_secs(5),
start,
last_logged: start,
checks: 0,
}
}
pub fn with_prefix(mut self, prefix: impl Into<String>) -> Self {
self.prefix = prefix.into();
self
}
pub fn with_heartbeat(mut self, every: Duration) -> Self {
self.heartbeat = every;
self
}
pub fn elapsed(&self) -> Duration {
self.start.elapsed()
}
pub fn timed_out(&self) -> bool {
self.start.elapsed() > self.timeout
}
pub fn tick(&mut self) {
self.checks += 1;
if self.last_logged.elapsed() >= self.heartbeat {
println!(
"{}still waiting for {}... via {} (check {}, limit {}s)",
self.prefix,
self.label,
self.method,
self.checks,
self.timeout.as_secs(),
);
self.last_logged = Instant::now();
}
}
}