use std::sync::Arc;
use std::sync::atomic::{AtomicU64, Ordering};
use std::time::Duration;
use netring::prelude::*;
struct SimulatedPool {
publishes: AtomicU64,
}
impl SimulatedPool {
async fn publish(&self) -> Result<(), netring::Error> {
tokio::task::yield_now().await;
self.publishes.fetch_add(1, Ordering::Relaxed);
Ok(())
}
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let iface = std::env::args().nth(1).unwrap_or_else(|| "lo".into());
let dur_secs: u64 = std::env::args()
.nth(2)
.and_then(|s| s.parse().ok())
.unwrap_or(10);
eprintln!("monitor_async_handler: capturing on {iface} for {dur_secs}s");
let sync_count = Arc::new(AtomicU64::new(0));
let pool = Arc::new(SimulatedPool {
publishes: AtomicU64::new(0),
});
let sync_count_h = Arc::clone(&sync_count);
let pool_h = Arc::clone(&pool);
let monitor = Monitor::builder()
.interface(&iface)
.protocol::<Tcp>()
.on::<FlowStarted<Tcp>>(move |_evt: &FlowStarted<Tcp>| {
sync_count_h.fetch_add(1, Ordering::Relaxed);
Ok(())
})
.on_async::<FlowStarted<Tcp>, _>(move |_evt: &FlowStarted<Tcp>| {
let pool = Arc::clone(&pool_h);
async move { pool.publish().await }
})
.build()?;
monitor.run_for(Duration::from_secs(dur_secs)).await?;
eprintln!(
"sync handler fires: {}",
sync_count.load(Ordering::Relaxed)
);
eprintln!(
"async pool publishes: {}",
pool.publishes.load(Ordering::Relaxed)
);
Ok(())
}