Skip to content

Commit

Permalink
fix: use indicatiff from crates.io
Browse files Browse the repository at this point in the history
Indicatif MultiProgress doesn't work well in the static context
This is basically a workaround for that.
A regular thread is spawned to update the progress in the background.

Note that the code might be refactored to the way it was before.
Once console-rs/indicatif#132 is merged.
  • Loading branch information
shenek committed May 29, 2020
1 parent a06bac5 commit cac2c35
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 30 deletions.
3 changes: 2 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ ui = ["indicatif"]
[dependencies]
futures = "0.3"
regex = "1"
tokio = {version="0.2", features=["tcp", "time", "process", "dns", "rt-threaded", "macros"]}
indicatif = {git="https://github.com/mibac138/indicatif", branch="mpb-tick", optional=true}
tokio = {version="0.2", features=["tcp", "time", "process", "dns", "rt-threaded", "macros", "blocking"]}
indicatif = {version="0.14", optional=true}

[dev-dependencies]
assert_cmd = "~0.12"
Expand Down
4 changes: 2 additions & 2 deletions src/options.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use regex;
use regex::Regex;
use std::net::IpAddr;

static DOMAIN_REGEX: &str =
Expand Down Expand Up @@ -42,7 +42,7 @@ fn validate_domain_and_port(domain_and_port: &str) -> Result<(String, u16), Stri

// check hostname
let hostname = parts[0].clone();
let regex = regex::Regex::new(DOMAIN_REGEX).unwrap();
let regex = Regex::new(DOMAIN_REGEX).unwrap();
let ip: Result<IpAddr, _> = hostname.parse();

if !regex.is_match(&hostname) && ip.is_err() {
Expand Down
39 changes: 14 additions & 25 deletions src/scanner.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use futures::future::join_all;
#[cfg(feature = "ui")]
use indicatif::{MultiProgress, ProgressBar, ProgressStyle, TickTimeLimit};
use indicatif::{MultiProgress, ProgressBar, ProgressStyle};
#[cfg(feature = "ui")]
use std::sync::{Arc, Mutex};
use std::{
Expand Down Expand Up @@ -58,7 +58,7 @@ pub fn wait(
instant: Instant,
) -> Vec<Pin<Box<dyn Future<Output = Option<u64>>>>> {
let multiple = Arc::new(Mutex::new(MultiProgress::new()));
hosts
let res = hosts
.iter()
.map(|addr| {
let pb = if let Some(timeout) = timeout {
Expand Down Expand Up @@ -87,7 +87,6 @@ pub fn wait(

let generator = ProgressGenerator {
instant,
multiple: multiple.clone(),
progress: Arc::new(Mutex::new(pb)),
};
Wait::new(
Expand All @@ -97,7 +96,13 @@ pub fn wait(
)
.wait_future()
})
.collect()
.collect();

// Spawn a thread which will Perform the drawing
// TODO this should be remove once indicatif Multi will become
// async compatible
tokio::task::spawn_blocking(move || multiple.lock().unwrap().join().unwrap());
res
}

pub fn wait_silent(
Expand Down Expand Up @@ -251,27 +256,20 @@ impl Generator for ProgressGenerator {
#[cfg(feature = "ui")]
pub struct ProgressGenerator {
instant: Instant,
multiple: Arc<Mutex<MultiProgress>>,
progress: Arc<Mutex<ProgressBar>>,
}

#[cfg(feature = "ui")]
impl Generator for ProgressGenerator {
fn generate_tick(&mut self) -> Pin<Box<dyn Future<Output = ()>>> {
let progress = self.progress.clone();
let multiple = self.multiple.clone();
let instant = self.instant;
self.instant = Instant::now();
Box::pin(async move {
progress
.lock()
.unwrap()
.inc(instant.elapsed().as_millis() as u64);
multiple
.lock()
.unwrap()
.tick(TickTimeLimit::Indefinite)
.unwrap_or(());
})
}

Expand All @@ -281,33 +279,24 @@ impl Generator for ProgressGenerator {

fn generate_error(&mut self) -> Pin<Box<dyn Future<Output = ()>>> {
let progress = self.progress.clone();
let multiple = self.multiple.clone();
Box::pin(async move {
let unlocked = progress.lock().unwrap();
unlocked.finish_with_message("✘");
multiple
.clone()
.lock()
.unwrap()
.tick(TickTimeLimit::Indefinite)
.unwrap_or(());

// wait for drawing thread to deal with this update
// TODO this should be remove once indicatif Multi will become
// async compatible
time::delay_for(Duration::from_millis(100)).await
})
}

fn generate_success(&mut self) -> Pin<Box<dyn Future<Output = u64>>> {
let progress = self.progress.clone();
let multiple = self.multiple.clone();
let instant = self.instant;
Box::pin(async move {
let unlocked = progress.lock().unwrap();
unlocked.set_message("✔");
unlocked.finish_at_current_pos();
multiple
.clone()
.lock()
.unwrap()
.tick(TickTimeLimit::Indefinite)
.unwrap_or(());
instant.elapsed().as_millis() as u64
})
}
Expand Down

0 comments on commit cac2c35

Please sign in to comment.