progress bar host API works

progress
Avril 4 years ago
parent 58643b6440
commit 34ff9847cb
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -1,2 +1 @@
Add lolistealer-like async progress bar handler to State (check state.rs) Rework logging macro calls to use new progress API

@ -28,7 +28,7 @@ use futures::{
async fn process_single(state: Arc<state::State>, path: impl AsRef<Path>) -> eyre::Result<()> async fn process_single(state: Arc<state::State>, path: impl AsRef<Path>) -> eyre::Result<()>
{ {
let path = path.as_ref(); let path = path.as_ref();
debug_assert!(!path.is_file(), "process_single() expected a file, but {:?} is not one.", path); debug_assert!(path.is_file(), "process_single() expected a file, but {:?} is not one.", path);
let _g = state.lock().await; let _g = state.lock().await;
debug!("{:?} Processing", path); debug!("{:?} Processing", path);

@ -102,22 +102,47 @@ async fn validate_config(config: config::Config) -> eyre::Result<config::Config>
async fn begin() -> eyre::Result<i32> async fn begin() -> eyre::Result<i32>
{ {
use futures::prelude::*;
install()?; install()?;
let state = Arc::new(state::State::new(validate_config(config::Config::default()).await
.wrap_err(eyre!("Failed to validate config"))?));
info!("Validated config OK");
if args::process(|file| {
let state = Arc::clone(&state);
use futures::future::TryFutureExt;
process(state, file).inspect_err(|err| eprintln!("{:?}", err))
}).await
.wrap_err(eyre!("One or more child workers failed to complete successfully"))?
.len() == 0
{ {
args::usage(); let (progress, progress_join) = {
} let bar = termprogress::progress::Bar::new(50);
let (p, join) = progress::host(bar);
Ok(0) (p, join.map(|bar| match bar {
Ok(bar) => {
bar.complete();
Ok(())
},
Err(panic) => {
println!();
Err(panic)
},
}))
};
let state = Arc::new(state::State::new(validate_config(config::Config::default()).await
.wrap_err(eyre!("Failed to validate config"))?,
progress));
info!("Validated config OK");
if args::process(|file| {
let state = Arc::clone(&state);
use futures::future::TryFutureExt;
process(state, file).inspect_err(|err| eprintln!("{:?}", err))
}).await
.wrap_err(eyre!("One or more child workers failed to complete successfully"))?
.len() == 0
{
args::usage();
}
//Cleanup deferred in new `async` block to drop `state` before this block is ran.
async move {
progress_join.await?;
Ok::<_, eyre::Report>(0)
}.map(|res| res.wrap_err(eyre!("Cleanup failed")))
}.await
} }
#[tokio::main] #[tokio::main]

@ -41,7 +41,10 @@ pub enum CommandKind
Bump(isize), Bump(isize),
BumpHigh(isize), BumpHigh(isize),
Set{low: Option<usize>, high: Option<usize>},
Refresh,
/// Add a task to the tasklist /// Add a task to the tasklist
/// ///
/// # Response /// # Response
@ -58,6 +61,7 @@ pub enum CommandKind
Many(Vec<CommandKind>), Many(Vec<CommandKind>),
} }
/// The type sent in response to a `Command`.
pub type Response = Option<Box<dyn std::any::Any + Send+ Sync + 'static>>; pub type Response = Option<Box<dyn std::any::Any + Send+ Sync + 'static>>;
#[derive(Debug)] #[derive(Debug)]
@ -131,7 +135,7 @@ impl State
} }
/// A handle to a running async progress bar /// A handle to a running async progress bar
#[derive(Debug, Clone)] #[derive(Debug)]
pub struct Handle<B = Bar> pub struct Handle<B = Bar>
where B: ProgressBar, where B: ProgressBar,
{ {
@ -145,6 +149,19 @@ where B: ProgressBar,
dead: watch::Receiver<bool>, dead: watch::Receiver<bool>,
} }
impl<B: ProgressBar> Clone for Handle<B>
{
fn clone(&self)->Self
{
Self {
chan: self.chan.clone(),
bar: self.bar.clone(),
state: self.state.clone(),
dead: self.dead.clone(),
}
}
}
impl<B: ProgressBar> Handle<B> impl<B: ProgressBar> Handle<B>
{ {
/// Is the worker alive? /// Is the worker alive?
@ -235,7 +252,7 @@ impl fmt::Display for WorkerCommError
} }
} }
/// Host a progress bar detached /// Host a progress bar and detach it
pub fn host<B: ProgressBar + Send + Sync + 'static>(bar: B) -> (Handle<B>, JoinHandle<B>) pub fn host<B: ProgressBar + Send + Sync + 'static>(bar: B) -> (Handle<B>, JoinHandle<B>)
{ {
let state = Arc::new(RwLock::new(Default::default())); let state = Arc::new(RwLock::new(Default::default()));
@ -255,6 +272,13 @@ pub fn host<B: ProgressBar + Send + Sync + 'static>(bar: B) -> (Handle<B>, JoinH
({ ({
let mut tasks = tasklist::TaskList::new(); let mut tasks = tasklist::TaskList::new();
macro_rules! update_bar { macro_rules! update_bar {
(refresh $($tt:tt)*) => {
{
let bar = bar.read().await;
bar.refresh();
update_bar!($($tt)*);
}
};
(to $state:ident $($tt:tt)*) => { (to $state:ident $($tt:tt)*) => {
{ {
let mut bar = bar.write().await; let mut bar = bar.write().await;
@ -301,6 +325,8 @@ pub fn host<B: ProgressBar + Send + Sync + 'static>(bar: B) -> (Handle<B>, JoinH
}; };
() => {}; () => {};
} }
update_bar!(refresh);
while let Some(Command(command, response)) = rx.recv().await { while let Some(Command(command, response)) = rx.recv().await {
let response = Arc::new(std::sync::Mutex::new(Some(response))); let response = Arc::new(std::sync::Mutex::new(Some(response)));
@ -362,6 +388,14 @@ pub fn host<B: ProgressBar + Send + Sync + 'static>(bar: B) -> (Handle<B>, JoinH
update_bar!(to state); update_bar!(to state);
}, },
CommandKind::Set{low: None, high: None} => (),
CommandKind::Set{low, high} => {
let mut state = state.write().await;
state.cur = low.unwrap_or(state.cur);
state.max = high.unwrap_or(state.max);
update_bar!(to state);
},
CommandKind::Line(line) => update_bar!(write line), CommandKind::Line(line) => update_bar!(write line),
CommandKind::LineErr(line) => update_bar!(write error line), CommandKind::LineErr(line) => update_bar!(write error line),
@ -371,8 +405,7 @@ pub fn host<B: ProgressBar + Send + Sync + 'static>(bar: B) -> (Handle<B>, JoinH
CommandKind::RemoveTask(id) => { CommandKind::RemoveTask(id) => {
send_response!(update_bar!(-task id title)); send_response!(update_bar!(-task id title));
}, },
CommandKind::Refresh => update_bar!(refresh),
//TODO: Title
CommandKind::Many(_) => unimplemented!(), CommandKind::Many(_) => unimplemented!(),
} }
} }

@ -14,13 +14,14 @@ use futures::{
}; };
/// Contains state for a set of operations /// Contains state for a set of operations
//TODO: Add progress bar handler in here, when we get around to adding it.
#[derive(Debug)] #[derive(Debug)]
pub struct State pub struct State
{ {
cfg: config::Config, cfg: config::Config,
mtx: Option<Semaphore>, mtx: Option<Semaphore>,
stop: RwLock<()>, stop: RwLock<()>,
progress: progress::Handle,
} }
/// Guard for operations inside state /// Guard for operations inside state
@ -30,12 +31,13 @@ pub struct Permit<'a>(RwLockReadGuard<'a, ()>, Option<SemaphorePermit<'a>>);
impl State impl State
{ {
/// Create a new state /// Create a new state
pub fn new(cfg: config::Config) -> Self pub fn new(cfg: config::Config, progress: progress::Handle) -> Self
{ {
Self { Self {
mtx: cfg.limit.map(|x| Semaphore::new(x.into())), mtx: cfg.limit.map(|x| Semaphore::new(x.into())),
cfg, cfg,
stop: RwLock::new(()), stop: RwLock::new(()),
progress,
} }
} }

Loading…
Cancel
Save