use { agave_thread_manager::*, log::info, std::{io::Read, path::PathBuf, time::Duration}, tokio::sync::oneshot, }; mod common; use common::*; fn main() -> anyhow::Result<()> { env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init(); let experiments = [ "examples/core_contention_dedicated_set.toml", "examples/core_contention_contending_set.toml", ]; for exp in experiments { info!("==================="); info!("Running {exp}"); let mut conf_file = PathBuf::from(env!("CARGO_MANIFEST_DIR")); conf_file.push(exp); let mut buf = String::new(); std::fs::File::open(conf_file)?.read_to_string(&mut buf)?; let cfg: ThreadManagerConfig = toml::from_str(&buf)?; let manager = ThreadManager::new(cfg).unwrap(); let tokio1 = manager.get_tokio("axum1"); tokio1.start_metrics_sampling(Duration::from_secs(1)); let tokio2 = manager.get_tokio("axum2"); tokio2.start_metrics_sampling(Duration::from_secs(1)); let workload_runtime = TokioRuntime::new( "LoadGenerator".to_owned(), TokioConfig { core_allocation: CoreAllocation::DedicatedCoreSet { min: 32, max: 64 }, ..Default::default() }, )?; let results = std::thread::scope(|scope| { let (tx1, rx1) = oneshot::channel(); let (tx2, rx2) = oneshot::channel(); scope.spawn(|| { tokio1.tokio.block_on(axum_main(8888, tx1)); }); scope.spawn(|| { tokio2.tokio.block_on(axum_main(8889, tx2)); }); // Wait for axum servers to start rx1.blocking_recv().unwrap(); rx2.blocking_recv().unwrap(); let join_handle = scope.spawn(|| workload_runtime.block_on(workload_main(&[8888, 8889], 1000))); join_handle.join().expect("Load generator crashed!") }); //print out the results of the bench run info!("Results are: {results:?}"); } Ok(()) }