Skip to content

Commit 0a5482e

Browse files
committed
Performance update
1 parent c39e785 commit 0a5482e

File tree

9 files changed

+329
-226
lines changed

9 files changed

+329
-226
lines changed

Cargo.toml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "bping"
3-
version = "2.0.5"
3+
version = "2.1.0"
44
description = "A command line utility to ping a website from anywhere in the world!"
55
authors = ["Firaenix <[email protected]>"]
66
edition = "2021"
@@ -52,7 +52,8 @@ bpaf = { version = "0.9.15", features = [
5252
"autocomplete",
5353
"batteries",
5454
] }
55-
tracing = "0.1.40"
56-
tracing-subscriber = "0.3.18"
55+
tracing = { version = "0.1", features = ["async-await"] }
56+
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
5757
rand = "0.8.5"
5858
regress = "0.10.1"
59+
tokio-retry = "0.3.0"

src/display/mod.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
mod ping_display;
22
mod print;
3-
// mod progress_bar;
4-
53
pub use print::*;
6-
// pub use progress_bar::*;
4+
mod progress;
5+
pub use progress::*;

src/display/ping_display.rs

Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6,91 +6,90 @@ use crate::{
66
options::Opts,
77
};
88
use colorful::{Color, Colorful};
9+
use indicatif::ProgressBar;
910
use std::*;
11+
use sync::Arc;
1012

11-
fn print_border(pb: &indicatif::ProgressBar, width: usize) {
13+
fn print_border(pb: &ProgressBar, width: usize) {
1214
pb.println("┌".to_string() + &"─".repeat(width - 2) + "┐");
1315
}
1416

15-
fn print_footer(pb: &indicatif::ProgressBar, width: usize) {
17+
fn print_footer(pb: &ProgressBar, width: usize) {
1618
pb.println("└".to_string() + &"─".repeat(width - 2) + "┘");
1719
}
1820

19-
pub fn display_success_ping(
20-
pb: &indicatif::ProgressBar,
21-
config: &Opts,
21+
async fn sleep_if_enabled(config: &'static Opts, duration: u64) {
22+
if !config.no_delay {
23+
tokio::time::sleep(std::time::Duration::from_millis(duration)).await;
24+
}
25+
}
26+
27+
pub async fn display_success_ping(
28+
pb: &ProgressBar,
29+
config: &'static Opts,
2230
endpoint: &str,
2331
jobres: &PerformIcmpResponseResultsItemResult,
2432
node_info: &PerformIcmpResponseNodeInfo,
2533
) {
26-
let width = 80; // Adjust this value as needed
34+
let width = 80;
2735
print_border(pb, width);
2836
format_ping_header(pb, config, endpoint, &jobres.ip_address, node_info);
2937

30-
// Display individual ping results
3138
let trips = jobres.trips as usize;
3239
for i in 0..trips {
3340
let time = jobres.min + (jobres.max - jobres.min) * (i as f64 / (trips - 1) as f64);
3441
pb.println(format!(
3542
"│ 64 bytes from {}: icmp_seq={} ttl=120 time={:.2} ms",
3643
jobres.ip_address, i, time
3744
));
38-
std::thread::sleep(std::time::Duration::from_millis(time as u64));
45+
sleep_if_enabled(config, time as u64).await;
3946
}
4047

41-
pb.println("│"); // Empty line for spacing
42-
43-
// Construct and print statistics line
48+
pb.println("│");
4449
pb.println(format!("│ --- {endpoint} ping statistics ---"));
4550

46-
std::thread::sleep(std::time::Duration::from_millis(250));
51+
sleep_if_enabled(config, 250).await;
4752

48-
// Print packet loss information
4953
pb.println(format!(
5054
"│ {} packets transmitted, {} packets received, {:.1}% packet loss",
5155
jobres.packets_sent,
5256
jobres.packets_recv,
5357
jobres.packet_loss * 100.0
5458
));
55-
std::thread::sleep(std::time::Duration::from_millis(250));
59+
sleep_if_enabled(config, 250).await;
5660

57-
// Print round-trip statistics
5861
pb.println(format!(
5962
"│ round-trip min/avg/max/stddev = {:.3}/{:.3}/{:.3}/{:.3} ms",
6063
jobres.min, jobres.avg, jobres.max, jobres.std_dev
6164
));
62-
std::thread::sleep(std::time::Duration::from_millis(250));
65+
sleep_if_enabled(config, 250).await;
6366

6467
print_footer(pb, width);
6568
}
6669

67-
pub fn display_failed_ping(
68-
pb: &indicatif::ProgressBar,
69-
config: &Opts,
70+
pub async fn display_failed_ping(
71+
pb: &ProgressBar,
72+
config: &'static Opts,
7073
jobres: &PerformIcmpResponseResultsItem,
7174
node_info: &PerformIcmpResponseNodeInfo,
7275
) {
73-
let width = 80; // Adjust this value as needed
76+
let width = 80;
7477
print_border(pb, width);
7578
let ip_address = jobres
7679
.result
7780
.as_ref()
7881
.map_or("Unknown".to_string(), |r| r.ip_address.clone());
7982
format_ping_header(pb, config, &jobres.endpoint, &ip_address, node_info);
8083

81-
// Request timeout for icmp_seq 0, 1, 2, 3
8284
let attempts = jobres.result.as_ref().map_or(4, |r| r.attempts as usize);
8385
for index in 0..attempts {
8486
pb.println(format!("│ Request timeout for icmp_seq {}", index));
85-
std::thread::sleep(std::time::Duration::from_millis(500));
87+
sleep_if_enabled(config, 500).await;
8688
}
8789

88-
// --- asdasdasd.com ping statistics ---
8990
pb.println(format!("│ --- {} ping statistics ---", jobres.endpoint));
91+
sleep_if_enabled(config, 250).await;
9092

91-
std::thread::sleep(std::time::Duration::from_millis(250));
92-
93-
// 5 packets transmitted, 0 packets received, 100.0% packet loss
9493
let error_string = if let Some(result) = &jobres.result {
9594
format!(
9695
"│ {} packets transmitted, {} packets received, {:.1}% packet loss",
@@ -104,16 +103,16 @@ pub fn display_failed_ping(
104103
attempts
105104
)
106105
};
107-
std::thread::sleep(std::time::Duration::from_millis(250));
106+
sleep_if_enabled(config, 250).await;
108107

109108
pb.println(format!("{}", error_string.color(Color::Red)));
110-
std::thread::sleep(std::time::Duration::from_millis(250));
109+
sleep_if_enabled(config, 250).await;
111110

112111
print_footer(pb, width);
113112
}
114113

115114
pub fn format_ping_header(
116-
pb: &indicatif::ProgressBar,
115+
pb: &ProgressBar,
117116
config: &Opts,
118117
endpoint: &str,
119118
ip_address: &str,

src/display/print.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1+
use std::sync::Arc;
2+
13
use indicatif::ProgressBar;
24
use tracing::error;
35

46
use crate::{models::types::PerformIcmpResponse, options::Opts};
57

68
use super::ping_display;
79

8-
pub async fn display_job(pb: &ProgressBar, config: &Opts, job_data: &PerformIcmpResponse) {
10+
pub async fn display_job(pb: &ProgressBar, config: &'static Opts, job_data: PerformIcmpResponse) {
911
for result in &job_data.results {
1012
if let Some(err) = &result.error {
1113
error!(?err, "Fatal job error.");
@@ -14,17 +16,18 @@ pub async fn display_job(pb: &ProgressBar, config: &Opts, job_data: &PerformIcmp
1416

1517
if let Some(job_result) = &result.result {
1618
if job_result.packet_loss == 1.0 {
17-
ping_display::display_failed_ping(pb, config, result, &job_data.node_info);
19+
ping_display::display_failed_ping(&pb, &config, result, &job_data.node_info).await;
1820
continue;
1921
}
2022

2123
ping_display::display_success_ping(
22-
pb,
23-
config,
24+
&pb,
25+
&config,
2426
&result.endpoint,
2527
job_result,
2628
&job_data.node_info,
27-
);
29+
)
30+
.await;
2831
}
2932

3033
pb.println("");

src/display/progress.rs

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
use color_eyre::eyre::Result;
2+
// progress.rs
3+
use indicatif::{ProgressBar, ProgressStyle};
4+
use std::sync::atomic::{AtomicUsize, Ordering};
5+
use std::sync::Arc;
6+
use std::time::Duration;
7+
use tokio::sync::mpsc::{self, Receiver, Sender};
8+
use tokio::task::JoinHandle;
9+
10+
use crate::display::display_job;
11+
use crate::models::types::PerformIcmpResponse;
12+
use crate::options::Opts;
13+
14+
pub struct ProgressDisplay {
15+
bar: ProgressBar,
16+
config: &'static Opts,
17+
18+
rx: Receiver<PerformIcmpResponse>,
19+
}
20+
21+
#[derive(Clone)]
22+
pub struct ProgressUpdater {
23+
bar: ProgressBar,
24+
tx: Sender<PerformIcmpResponse>,
25+
}
26+
27+
impl Drop for ProgressUpdater {
28+
fn drop(&mut self) {
29+
self.bar.finish_with_message("Completed");
30+
}
31+
}
32+
33+
impl ProgressUpdater {
34+
pub(crate) async fn display_job(
35+
&self,
36+
job: progenitor::progenitor_client::ResponseValue<
37+
crate::models::types::PerformIcmpResponse,
38+
>,
39+
) {
40+
let _ = self.tx.send(job.into_inner()).await;
41+
self.bar.inc(1);
42+
}
43+
}
44+
45+
impl ProgressDisplay {
46+
pub fn new(config: &'static Opts) -> Result<(Self, ProgressUpdater)> {
47+
let mut spinner_style = ProgressStyle::default_spinner()
48+
.tick_chars("-\\|/")
49+
.template("{spinner:.green} {msg:.cyan/blue} [{elapsed_precise}] {pos}/{len}")?;
50+
51+
let bar = ProgressBar::new((config.attempts * config.regions.len()) as u64);
52+
53+
let world_ticker = format!("{}", console::Emoji("🌍🌍🌎🌎🌏🌏🌎🌎🌍🌍", "-\\|/"));
54+
spinner_style = spinner_style.tick_chars(&world_ticker);
55+
bar.enable_steady_tick(Duration::from_millis(350));
56+
57+
bar.set_style(spinner_style);
58+
59+
let (tx, rx) = mpsc::channel(config.concurrency);
60+
61+
Ok((
62+
Self {
63+
bar: bar.clone(),
64+
config,
65+
rx,
66+
},
67+
ProgressUpdater { bar, tx },
68+
))
69+
}
70+
71+
pub async fn display_job_thread(&mut self) {
72+
while let Some(x) = self.rx.recv().await {
73+
display_job(&self.bar, self.config, x).await;
74+
}
75+
}
76+
}

src/display/progress_bar.rs

Lines changed: 0 additions & 40 deletions
This file was deleted.

0 commit comments

Comments
 (0)