Skip to content

Commit

Permalink
Performance update
Browse files Browse the repository at this point in the history
  • Loading branch information
Firaenix committed Dec 7, 2024
1 parent c39e785 commit 0a5482e
Show file tree
Hide file tree
Showing 9 changed files with 329 additions and 226 deletions.
7 changes: 4 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "bping"
version = "2.0.5"
version = "2.1.0"
description = "A command line utility to ping a website from anywhere in the world!"
authors = ["Firaenix <[email protected]>"]
edition = "2021"
Expand Down Expand Up @@ -52,7 +52,8 @@ bpaf = { version = "0.9.15", features = [
"autocomplete",
"batteries",
] }
tracing = "0.1.40"
tracing-subscriber = "0.3.18"
tracing = { version = "0.1", features = ["async-await"] }
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
rand = "0.8.5"
regress = "0.10.1"
tokio-retry = "0.3.0"
5 changes: 2 additions & 3 deletions src/display/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
mod ping_display;
mod print;
// mod progress_bar;

pub use print::*;
// pub use progress_bar::*;
mod progress;
pub use progress::*;
57 changes: 28 additions & 29 deletions src/display/ping_display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,91 +6,90 @@ use crate::{
options::Opts,
};
use colorful::{Color, Colorful};
use indicatif::ProgressBar;
use std::*;
use sync::Arc;

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

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

pub fn display_success_ping(
pb: &indicatif::ProgressBar,
config: &Opts,
async fn sleep_if_enabled(config: &'static Opts, duration: u64) {
if !config.no_delay {
tokio::time::sleep(std::time::Duration::from_millis(duration)).await;
}
}

pub async fn display_success_ping(
pb: &ProgressBar,
config: &'static Opts,
endpoint: &str,
jobres: &PerformIcmpResponseResultsItemResult,
node_info: &PerformIcmpResponseNodeInfo,
) {
let width = 80; // Adjust this value as needed
let width = 80;
print_border(pb, width);
format_ping_header(pb, config, endpoint, &jobres.ip_address, node_info);

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

pb.println("│"); // Empty line for spacing

// Construct and print statistics line
pb.println("│");
pb.println(format!("│ --- {endpoint} ping statistics ---"));

std::thread::sleep(std::time::Duration::from_millis(250));
sleep_if_enabled(config, 250).await;

// Print packet loss information
pb.println(format!(
"│ {} packets transmitted, {} packets received, {:.1}% packet loss",
jobres.packets_sent,
jobres.packets_recv,
jobres.packet_loss * 100.0
));
std::thread::sleep(std::time::Duration::from_millis(250));
sleep_if_enabled(config, 250).await;

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

print_footer(pb, width);
}

pub fn display_failed_ping(
pb: &indicatif::ProgressBar,
config: &Opts,
pub async fn display_failed_ping(
pb: &ProgressBar,
config: &'static Opts,
jobres: &PerformIcmpResponseResultsItem,
node_info: &PerformIcmpResponseNodeInfo,
) {
let width = 80; // Adjust this value as needed
let width = 80;
print_border(pb, width);
let ip_address = jobres
.result
.as_ref()
.map_or("Unknown".to_string(), |r| r.ip_address.clone());
format_ping_header(pb, config, &jobres.endpoint, &ip_address, node_info);

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

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

std::thread::sleep(std::time::Duration::from_millis(250));

// 5 packets transmitted, 0 packets received, 100.0% packet loss
let error_string = if let Some(result) = &jobres.result {
format!(
"│ {} packets transmitted, {} packets received, {:.1}% packet loss",
Expand All @@ -104,16 +103,16 @@ pub fn display_failed_ping(
attempts
)
};
std::thread::sleep(std::time::Duration::from_millis(250));
sleep_if_enabled(config, 250).await;

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

print_footer(pb, width);
}

pub fn format_ping_header(
pb: &indicatif::ProgressBar,
pb: &ProgressBar,
config: &Opts,
endpoint: &str,
ip_address: &str,
Expand Down
13 changes: 8 additions & 5 deletions src/display/print.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
use std::sync::Arc;

use indicatif::ProgressBar;
use tracing::error;

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

use super::ping_display;

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

if let Some(job_result) = &result.result {
if job_result.packet_loss == 1.0 {
ping_display::display_failed_ping(pb, config, result, &job_data.node_info);
ping_display::display_failed_ping(&pb, &config, result, &job_data.node_info).await;
continue;
}

ping_display::display_success_ping(
pb,
config,
&pb,
&config,
&result.endpoint,
job_result,
&job_data.node_info,
);
)
.await;
}

pb.println("");
Expand Down
76 changes: 76 additions & 0 deletions src/display/progress.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
use color_eyre::eyre::Result;
// progress.rs
use indicatif::{ProgressBar, ProgressStyle};
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
use std::time::Duration;
use tokio::sync::mpsc::{self, Receiver, Sender};
use tokio::task::JoinHandle;

use crate::display::display_job;
use crate::models::types::PerformIcmpResponse;
use crate::options::Opts;

pub struct ProgressDisplay {
bar: ProgressBar,
config: &'static Opts,

rx: Receiver<PerformIcmpResponse>,
}

#[derive(Clone)]
pub struct ProgressUpdater {
bar: ProgressBar,
tx: Sender<PerformIcmpResponse>,
}

impl Drop for ProgressUpdater {
fn drop(&mut self) {
self.bar.finish_with_message("Completed");
}
}

impl ProgressUpdater {
pub(crate) async fn display_job(
&self,
job: progenitor::progenitor_client::ResponseValue<
crate::models::types::PerformIcmpResponse,
>,
) {
let _ = self.tx.send(job.into_inner()).await;
self.bar.inc(1);
}
}

impl ProgressDisplay {
pub fn new(config: &'static Opts) -> Result<(Self, ProgressUpdater)> {
let mut spinner_style = ProgressStyle::default_spinner()
.tick_chars("-\\|/")
.template("{spinner:.green} {msg:.cyan/blue} [{elapsed_precise}] {pos}/{len}")?;

let bar = ProgressBar::new((config.attempts * config.regions.len()) as u64);

let world_ticker = format!("{}", console::Emoji("🌍🌍🌎🌎🌏🌏🌎🌎🌍🌍", "-\\|/"));
spinner_style = spinner_style.tick_chars(&world_ticker);
bar.enable_steady_tick(Duration::from_millis(350));

bar.set_style(spinner_style);

let (tx, rx) = mpsc::channel(config.concurrency);

Ok((
Self {
bar: bar.clone(),
config,
rx,
},
ProgressUpdater { bar, tx },
))
}

pub async fn display_job_thread(&mut self) {
while let Some(x) = self.rx.recv().await {
display_job(&self.bar, self.config, x).await;
}
}
}
40 changes: 0 additions & 40 deletions src/display/progress_bar.rs

This file was deleted.

Loading

0 comments on commit 0a5482e

Please sign in to comment.