Started impl of feature `progress-reactive`: Addded `.resize_bar()` (`CommandKind::Resize`) to update progress bar max size to fit recalculated terminal width.

Fortune for leanify-many's current commit: Blessing − 吉
safe-cancel-interrupt
Avril 1 week ago
parent 29d45438ee
commit 8d8f932081
Signed by: flanchan
GPG Key ID: 284488987C31F630

25
Cargo.lock generated

@ -2,12 +2,6 @@
# It is not intended for manual editing.
version = 4
[[package]]
name = "arc-swap"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d25d88fd6b8041580a654f9d0c581a047baee2b3efee13275f2fc392fc75034"
[[package]]
name = "atty"
version = "0.2.14"
@ -184,7 +178,7 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "leanify-many"
version = "1.2.0+1"
version = "1.2.1+1"
dependencies = [
"cfg-if",
"futures",
@ -194,6 +188,8 @@ dependencies = [
"pin-project",
"recolored",
"rustc_version",
"signal-hook",
"terminal_size",
"termprogress",
"tokio",
]
@ -401,13 +397,22 @@ version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]]
name = "signal-hook"
version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801"
dependencies = [
"libc",
"signal-hook-registry",
]
[[package]]
name = "signal-hook-registry"
version = "1.2.1"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3e12110bc539e657a646068aaf5eb5b63af9d0c1f7b29c97113fad80e15f035"
checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1"
dependencies = [
"arc-swap",
"libc",
]

@ -1,6 +1,6 @@
[package]
name = "leanify-many"
version = "1.2.0+1"
version = "1.2.1+1"
description = "spawn leanify subprocesses"
authors = ["Avril <flanchan@cumallover.me>"]
edition = "2018"
@ -16,10 +16,10 @@ lto = "fat"
codegen-units = 1
[features]
default = ["splash", "progress", "colour", "collect_err", "shutdown"]
default = ["splash", "progress-reactive", "colour", "collect_err", "shutdown"]
# Enable progress bar
progress = ["termprogress", "pin-project"]
progress = ["termprogress", "pin-project", "terminal_size"]
# Enable threaded scheduler
#
@ -48,6 +48,8 @@ collect_err = []
# Without this feature enabled, `leanify` subprocesses will receive terminating `SIGINT`s as normal.
shutdown = ["libc"]
# TODO: Implement this to: Capture `SIGWINCH` events and re-size + re-render the progress bar to the new terminal width. (XXX: Use a background thread (outside the thread-pool, as it's blocking) listening on `signal_hooks::Signals.forever()` for this that sends events through a shared Tokio `CondVar<TerminalWidth>` notify_all() call.)
progress-reactive = ["progress", "tokio/signal", "signal-hook"]
[dependencies]
lazy_static = "1.4"
@ -59,6 +61,8 @@ recolored = { version = "1.9", optional = true }
num_cpus = "1.13"
pin-project = {version = "0.4", optional = true}
libc = { version = "0.2.171", features = ["align"], optional = true }
terminal_size = { version = "^0.1.13", optional = true }
signal-hook = { version = "0.3.17", features = ["iterator"], optional = true }
[build-dependencies]
rustc_version = "0.2"

@ -31,9 +31,8 @@ mod maybe_single;
#[cfg(feature="progress")] mod task_list;
#[cfg(feature="progress")] mod progress;
async fn work() -> Result<(), Box<dyn std::error::Error>>
async fn work() -> Result<Option<std::num::NonZeroI32>, Box<dyn std::error::Error>>
{
//println!("umm {}", colour::style(colour!(Color::Blue), "hiii"));
let args = arg::parse_args().await.with_prefix("failed to parse args")?;
let leanify = leanify::find_binary().with_prefix("Couldn't find leanify binary")?;
@ -85,13 +84,17 @@ async fn work() -> Result<(), Box<dyn std::error::Error>>
}
},
_ => args.max_children,
}, get_shutdown_future(&args.flags).fuse()).await
}, get_shutdown_future(&args.flags).fuse()).await
.map(|_| None) //TODO: Can the shutdown future set an `is_interrupted` var we can use to return a non-zero exit code from a SIGINT graceful shutdown here (e.g. `is_interrupted.then_some(1)`)? Do something like this...
}
#[tokio::main]
async fn main() {
prettify_expect(work().await.map_err(|e| e.to_string()), "exited with error");
if let Some(code) = prettify_expect(work().await.map_err(|e| e.to_string()), "exited with error") {
// Exiting with error (non-zero) code
std::process::exit(code.get());
}
}
#[inline] fn prettify_expect<T,E,S>(res: Result<T,E>, msg: S) -> T

@ -19,6 +19,7 @@ use std::{
self,
Once,
},
num::NonZeroUsize,
};
use tokio::{
sync::{
@ -68,6 +69,10 @@ pub enum CommandKind
Complete,
Resize {
to: Option<NonZeroUsize>,
},
Many(Vec<CommandKind>),
}
@ -312,6 +317,15 @@ impl ProgressSender
self.send_command(CommandKind::BumpLow(by)).await
}
/// Resize the whole bar to either a specific size, or to query the terminal size.
///
/// Currently, the terminal size is grabbed from `stdout` or `stderr` if possible.
/// If `None` is passed and the output of `stdout` *and* `stderr` are not TTYs, no resize will take place.
pub async fn resize_bar(&mut self, to: Option<NonZeroUsize>) -> Result<CommandWaiter, Error>
{
self.send_command(CommandKind::Resize { to }).await
}
/// Add a task to the worker's progress bar title line
///
/// This function returns a [TaskWaiter]`TaskWaiter` future, upon successful `await`ing will yield the task's ID.
@ -382,7 +396,6 @@ pub fn create_progress<P: ProgressBar + WithTitle + Send + 'static,
low: 0,
};
let (stat_tx, stat_rx) = watch::channel(stat.clone());
let handle = {
let handle = task::spawn(async move {
@ -444,6 +457,29 @@ pub fn create_progress<P: ProgressBar + WithTitle + Send + 'static,
let mut has_blanked = false;
while let Some(command) = commands.next().await {
match command {
CommandKind::Resize { to: None } => {
use std::os::fd::{
AsFd,
AsRawFd,
};
if let Some((w, _)) = terminal_size::terminal_size()
.or_else(|| terminal_size::terminal_size_using_fd(std::io::stderr().as_fd().as_raw_fd()))
{
// Blank the line, and tell to redraw after the dimension update.
progress.blank();
has_blanked = true;
progress.update_dimensions(w.0 as usize);
}
},
CommandKind::Resize { to: Some(to) } => {
// Blank the line, and tell to redraw after the dimension update.
progress.blank();
has_blanked = true;
progress.update_dimensions(to.get());
},
CommandKind::BumpHigh(high) => {
let stat = stat.to_mut();
stat.high+=high;

@ -143,6 +143,12 @@ where I: IntoIterator<Item=T>,
progress::create_progress::<termprogress::silent::Silent,_>(files.len(), iter::empty())
}
};
#[cfg(feature="progress-reactive")]
let _size_handle = {
let mut progress = progress.clone();
todo!("progress-reactive: Spawn the `signal_hooks` thread and set up the Tokio `CondVar` to wait on in a background task, sending `Resize{None} to `progress` when an event comes in.");
};
let display = {
#[cfg(feature="progress")] let mut progress = progress.clone();
@ -191,7 +197,7 @@ where I: IntoIterator<Item=T>,
let process = Arc::clone(&process);
let mut tx = tx.clone();
let flags = flags.clone();
let flags = flags.clone(); // XXX: Can we remove this clone somehow? It's kinda big this structure and we only need to do this because of not being able to exclude 'cli from `+ use<>` in the `async fn do_work()` as it's an `async fn` and not a `fn() -> impl Future`...
#[cfg(feature="progress")] let mut progress = progress.clone();
@ -288,7 +294,7 @@ where I: IntoIterator<Item=T>,
Ok(v) => Box::new(v),
};
for failed in results
for failed in results
{
#[cfg(feature="progress")] progress.eprintln(format!("[{}] Child panic {:?}", colour::style(colour!(Color::BrightRed), "e"), failed)).await?.await?;
#[cfg(not(feature="progress"))] eprintln!("[{}] Child panic {:?}", colour::style(colour!(Color::BrightRed), "e"), failed);

Loading…
Cancel
Save