blob: 72e364db3c05da70bc5bb5cd5c5db42e0f3063a0 [file] [log] [blame]
use crate::analytics::report_builder::BenchmarkReportBuilder;
use crate::args::common::IggyBenchArgs;
use crate::benchmarks::benchmark::Benchmarkable;
use crate::plot::{plot_chart, ChartType};
use crate::utils::server_starter::start_server_if_needed;
use futures::future::select_all;
use iggy::error::IggyError;
use iggy_benchmark_report::hardware::BenchmarkHardware;
use iggy_benchmark_report::params::BenchmarkParams;
use integration::test_server::TestServer;
use std::path::Path;
use std::time::Duration;
use tokio::time::sleep;
use tracing::{error, info};
pub struct BenchmarkRunner {
pub args: Option<IggyBenchArgs>,
pub test_server: Option<TestServer>,
}
impl BenchmarkRunner {
pub fn new(args: IggyBenchArgs) -> Self {
Self {
args: Some(args),
test_server: None,
}
}
pub async fn run(&mut self) -> Result<(), IggyError> {
let mut args = self.args.take().unwrap();
self.test_server = start_server_if_needed(&mut args).await;
let transport = args.transport();
let server_addr = args.server_address();
info!("Starting to benchmark: {transport} with server: {server_addr}",);
let mut benchmark: Box<dyn Benchmarkable> = args.into();
let mut join_handles = benchmark.run().await?;
info!("Benchmarking finished");
let mut individual_metrics = Vec::new();
while !join_handles.is_empty() {
let (result, _index, remaining) = select_all(join_handles).await;
join_handles = remaining;
match result {
Ok(r) => individual_metrics.push(r),
Err(e) => return Err(e),
}
}
info!("All actors joined!");
let hardware =
BenchmarkHardware::get_system_info_with_identifier(benchmark.args().identifier());
let params = BenchmarkParams::from(benchmark.args());
let report = BenchmarkReportBuilder::build(
hardware,
params,
individual_metrics,
benchmark.args().moving_average_window(),
)
.await;
// Sleep just to see result prints after all tasks are joined (they print per-actor results)
sleep(Duration::from_millis(10)).await;
report.print_summary();
if let Some(output_dir) = benchmark.args().output_dir() {
// Generate the full output path using the directory name generator
let dir_name = benchmark.args().generate_dir_name();
let full_output_path = Path::new(&output_dir)
.join(dir_name)
.to_string_lossy()
.to_string();
// Dump the report to JSON
report.dump_to_json(&full_output_path);
// Generate the plots
plot_chart(&report, &full_output_path, ChartType::Throughput).map_err(|e| {
error!("Failed to generate plots: {e}");
IggyError::CannotWriteToFile
})?;
plot_chart(&report, &full_output_path, ChartType::Latency).map_err(|e| {
error!("Failed to generate plots: {e}");
IggyError::CannotWriteToFile
})?;
}
Ok(())
}
}