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));
});
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!")
});
info!("Results are: {results:?}");
}
Ok(())
}