Skip to content

Commit 2cb3ef2

Browse files
authored
Merge pull request #1536 from cgwalters/ostree-lock-spinner-async
ostree: Use indicatif + async for lock wait
2 parents 7a82af6 + fa81c1e commit 2cb3ef2

File tree

2 files changed

+40
-13
lines changed

2 files changed

+40
-13
lines changed

crates/ostree-ext/src/sysroot.rs

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ use std::ops::Deref;
44

55
use anyhow::Result;
66

7+
use crate::utils::async_task_with_spinner;
8+
79
/// A locked system root.
810
#[derive(Debug)]
911
pub struct SysrootLock {
@@ -35,20 +37,17 @@ impl SysrootLock {
3537
/// immediately, a status message will be printed to standard output.
3638
/// The lock will be unlocked when this object is dropped.
3739
pub async fn new_from_sysroot(sysroot: &ostree::Sysroot) -> Result<Self> {
38-
let mut printed = false;
39-
loop {
40-
if sysroot.try_lock()? {
41-
return Ok(Self {
42-
sysroot: sysroot.clone(),
43-
unowned: false,
44-
});
45-
}
46-
if !printed {
47-
eprintln!("Waiting for sysroot lock...");
48-
printed = true;
49-
}
50-
tokio::time::sleep(std::time::Duration::from_secs(3)).await;
40+
if sysroot.try_lock()? {
41+
return Ok(Self {
42+
sysroot: sysroot.clone(),
43+
unowned: false,
44+
});
5145
}
46+
async_task_with_spinner("Waiting for sysroot lock...", sysroot.lock_future()).await?;
47+
Ok(Self {
48+
sysroot: sysroot.clone(),
49+
unowned: false,
50+
})
5251
}
5352

5453
/// This function should only be used when you have locked the sysroot

crates/ostree-ext/src/utils.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,29 @@
1+
use std::{future::Future, time::Duration};
12

3+
/// Call an async task function, and write a message to stdout
4+
/// with an automatic spinner to show that we're not blocked.
5+
/// Note that generally the called function should not output
6+
/// anything to stdout as this will interfere with the spinner.
7+
pub(crate) async fn async_task_with_spinner<F, T>(msg: &str, f: F) -> T
8+
where
9+
F: Future<Output = T>,
10+
{
11+
let pb = indicatif::ProgressBar::new_spinner();
12+
let style = indicatif::ProgressStyle::default_bar();
13+
pb.set_style(style.template("{spinner} {msg}").unwrap());
14+
pb.set_message(msg.to_string());
15+
pb.enable_steady_tick(Duration::from_millis(150));
16+
let r = f.await;
17+
pb.finish_and_clear();
18+
r
19+
}
20+
21+
#[cfg(test)]
22+
mod tests {
23+
use super::*;
24+
25+
#[tokio::test]
26+
async fn test_spinner() {
27+
async_task_with_spinner("Testing...", tokio::time::sleep(Duration::from_secs(5))).await
28+
}
29+
}

0 commit comments

Comments
 (0)