From 25cdd0f1a0ae0afab5e34b18ea00f1727d7176a9 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Thu, 8 Apr 2021 17:16:07 +0200 Subject: Fix: Update the progress bar each second This patch tries to work around a longer-than-1-sec blocking future while waiting for the channel .recv() call in the LogReceiver. The issue at hand is: If the channel does not produce log output for longer than 1 second, the progress bar won't be `tick()`ed for that amount of time. That leads to progress bars that seem to block (no update of the time in the progress bar output), which might confuse users. This patch works around that by wrapping the recv() in a timeout future and then catch the timeout, ping the progress bar and try to `recv()` again. Signed-off-by: Matthias Beyer --- src/endpoint/scheduler.rs | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/endpoint/scheduler.rs b/src/endpoint/scheduler.rs index 5f0882b..0215938 100644 --- a/src/endpoint/scheduler.rs +++ b/src/endpoint/scheduler.rs @@ -331,7 +331,29 @@ impl<'a> LogReceiver<'a> { let mut accu = vec![]; let mut logfile = self.get_logfile().await.transpose()?; - while let Some(logitem) = self.log_receiver.recv().await { + // The timeout for the log-receive-timeout + // + // We're using a rather small timeout of just 250ms here, because we have some worktime + // overhead as well, and we want to ping the progressbar for the process in a way so that + // it updates each second. + // Having a timeout of 1 sec proofed to be too long to update the time field in the + // progress bar secondly. + let timeout_duration = std::time::Duration::from_millis(250); + + loop { + // Timeout for receiving from the log receiver channel + // This way we can update (`tick()`) the progress bar and show the user that things are + // happening, even if there was no log output for several seconds. + let logitem = match tokio::time::timeout(timeout_duration, self.log_receiver.recv()).await { + Err(_ /* elapsed */) => { + self.bar.tick(); // just ping the progressbar here + continue + }, + + Ok(None) => break, // if the log is empty, we're done + Ok(Some(logitem)) => logitem, + }; + if let Some(lf) = logfile.as_mut() { lf.write_all(logitem.display()?.to_string().as_bytes()) .await?; -- cgit v1.2.3