#[cfg(feature = "high-perf")]
use http_handle::Server;
#[cfg(feature = "high-perf")]
use http_handle::perf_server::{PerfLimits, start_high_perf};
#[cfg(feature = "high-perf")]
use std::net::TcpListener;
#[cfg(feature = "high-perf")]
use std::thread;
#[cfg(feature = "high-perf")]
use std::time::Duration;
#[cfg(feature = "high-perf")]
#[global_allocator]
static ALLOC: dhat::Alloc = dhat::Alloc;
#[cfg(feature = "high-perf")]
const ITERATIONS: usize = 1024;
#[cfg(feature = "high-perf")]
fn main() {
let _profiler = dhat::Profiler::new_heap();
let probe = TcpListener::bind("127.0.0.1:0").expect("probe bind");
let addr = probe.local_addr().expect("addr").to_string();
drop(probe);
let root = tempfile::TempDir::new().expect("tempdir");
std::fs::write(
root.path().join("test.html"),
b"<html><body>Test Content</body></html>",
)
.expect("write body");
std::fs::create_dir(root.path().join("404")).expect("404 dir");
std::fs::write(root.path().join("404/index.html"), b"404")
.expect("write 404");
let document_root =
root.path().to_str().expect("utf8 path").to_string();
let server_addr = addr.clone();
let _server_thread = thread::spawn(move || {
let rt = tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.expect("server rt");
rt.block_on(async {
let server = Server::builder()
.address(&server_addr)
.document_root(&document_root)
.build()
.expect("server build");
let _ =
start_high_perf(server, PerfLimits::default()).await;
});
});
let client_rt = tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.expect("client rt");
client_rt.block_on(async {
for _ in 0..200 {
if tokio::net::TcpStream::connect(&addr).await.is_ok() {
return;
}
tokio::time::sleep(Duration::from_millis(5)).await;
}
panic!("perf_server never bound on {addr}");
});
client_rt.block_on(async {
use tokio::io::{AsyncReadExt, AsyncWriteExt};
const REQUEST: &[u8] = b"GET /test.html HTTP/1.1\r\nHost: b\r\nConnection: close\r\n\r\n";
for _ in 0..ITERATIONS {
let mut s = tokio::net::TcpStream::connect(&addr)
.await
.expect("connect");
s.write_all(REQUEST).await.expect("write");
let mut sink = Vec::with_capacity(256);
let _ = s.read_to_end(&mut sink).await.expect("read");
}
});
println!(
"[dhat] {ITERATIONS} roundtrips complete; \
dhat-heap.json written on Profiler drop."
);
}
#[cfg(not(feature = "high-perf"))]
fn main() {
eprintln!(
"Enable the 'high-perf' feature: cargo run --release --example dhat --features high-perf"
);
}