aboutsummaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/main.rs62
1 files changed, 55 insertions, 7 deletions
diff --git a/src/main.rs b/src/main.rs
index 352315b..705bd07 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -5,6 +5,8 @@ use std::ops::RangeInclusive;
use std::pin::Pin;
use std::process::ExitCode;
use std::sync::Arc;
+use time::format_description::well_known::Iso8601;
+use time::UtcDateTime;
use clap::Parser;
use http_body_util::Full;
@@ -20,6 +22,7 @@ use rand::prelude::*;
use rand_pcg::Pcg64;
use rand_seeder::Seeder;
use tokio::net::TcpListener;
+use tokio::sync::Mutex;
use tracing::level_filters::LevelFilter;
use tracing_subscriber::EnvFilter;
@@ -55,6 +58,9 @@ struct Args {
links_max: u16,
#[arg(long)]
href_prefix: Option<String>,
+ /// tiem in seconds between reporting wasted resources
+ #[arg(long, default_value_t = 3600)]
+ waste_log: u64,
}
#[tokio::main]
@@ -71,7 +77,36 @@ async fn main() -> Result<ExitCode, Box<dyn std::error::Error + Send + Sync>> {
)
.init();
- let generator = PageGenerator::new(&args);
+ let stats = Arc::new(Mutex::new(StatsReport {
+ seconds_wasted: 0.0,
+ bytes_wasted: 0,
+ period_start: UtcDateTime::now(),
+ }));
+
+ {
+ let stats = stats.clone();
+ let waste_log = args.waste_log;
+ tokio::task::spawn(async move {
+ let mut interval =
+ tokio::time::interval(std::time::Duration::from_secs(waste_log));
+ loop {
+ interval.tick().await;
+ let mut stats = stats.lock().await;
+ let new_period = UtcDateTime::now();
+ tracing::info!(
+ seconds_wasted = stats.seconds_wasted,
+ bytes_wasted = stats.bytes_wasted,
+ period_start = stats.period_start.format(&Iso8601::DEFAULT).unwrap(),
+ period_end = new_period.format(&Iso8601::DEFAULT).unwrap(),
+ );
+ stats.seconds_wasted = 0.0;
+ stats.bytes_wasted = 0;
+ stats.period_start = new_period;
+ }
+ });
+ }
+
+ let generator = PageGenerator::new(&args, stats.clone());
generator.stats();
@@ -100,7 +135,7 @@ async fn main() -> Result<ExitCode, Box<dyn std::error::Error + Send + Sync>> {
}
}
-#[derive(Debug, Clone)]
+#[derive(Clone)]
struct RandomPageService {
pub ctx: Arc<PageGenerator>,
}
@@ -136,7 +171,6 @@ impl Service<Request<hyper::body::Incoming>> for RandomPageService {
}
}
-#[derive(Debug)]
struct PageGenerator {
seed: String,
segments: u8,
@@ -144,12 +178,13 @@ struct PageGenerator {
paragraph_size: RangeInclusive<u16>,
n_links: RangeInclusive<u16>,
delay: RangeInclusive<u64>,
+ stats: Arc<Mutex<StatsReport>>,
dict: Vec<&'static str>,
dict_set: HashSet<&'static str>,
}
impl PageGenerator {
- fn new(args: &Args) -> Self {
+ fn new(args: &Args, stats: Arc<Mutex<StatsReport>>) -> Self {
let dictionary_data = include_bytes!(env!("DICTIONARY_FILE_PATH"));
let dictionary_string: &'static str =
std::str::from_utf8(dictionary_data).unwrap();
@@ -161,6 +196,7 @@ impl PageGenerator {
..=(args.paragraph_max.max(args.paragraph_min)),
n_links: (args.links_min)..=(args.links_max.max(args.links_min)),
delay: args.delay_min..=(args.delay_max.max(args.delay_min)),
+ stats,
dict: dictionary_string.split_whitespace().collect(),
dict_set: dictionary_string.split_whitespace().collect(),
}
@@ -242,9 +278,9 @@ impl PageGenerator {
.collect::<Vec<String>>()
.join("");
- tracing::info!(route, delay);
+ tracing::debug!(route, delay);
- Ok(format!(
+ let body = format!(
"<!DOCTYPE html>\
<html>\
<head>\
@@ -258,7 +294,13 @@ impl PageGenerator {
{random_links}\
</body>\
</html>",
- ))
+ );
+ {
+ let mut stats = self.stats.lock().await;
+ stats.seconds_wasted += delay.unwrap_or_default() as f64 / 1000.0;
+ stats.bytes_wasted += body.len() as u128;
+ }
+ Ok(body)
}
fn random_route_link(&self, rng: &mut Pcg64) -> String {
let n_segments = rng.gen_range(1..=self.segments);
@@ -276,6 +318,12 @@ impl PageGenerator {
}
}
+struct StatsReport {
+ seconds_wasted: f64,
+ bytes_wasted: u128,
+ period_start: UtcDateTime,
+}
+
pub fn build_dict() -> Vec<&'static str> {
let dictionary_data = include_bytes!(env!("DICTIONARY_FILE_PATH"));
let dictionary_string: &'static str =