use std::time::Duration;
use nlink::netlink::{Connection, Route, RtnetlinkGroup};
use nlink::netlink::resync::{ResyncedEvent, ResyncMarker};
use tokio_stream::StreamExt;
#[tokio::main]
async fn main() -> nlink::Result<()> {
let mut conn = Connection::<Route>::new()?;
conn.subscribe(&[RtnetlinkGroup::Link])?;
println!("subscribed to RTNLGRP_LINK; Ctrl-C to exit");
println!("event ENOBUFS will trigger an automatic re-snapshot");
let mut events = conn.events();
let mut event_count = 0usize;
let mut resync_count = 0usize;
let deadline = std::time::Instant::now() + Duration::from_secs(10);
while std::time::Instant::now() < deadline {
let evt = tokio::select! {
evt = events.next() => evt,
_ = tokio::time::sleep(Duration::from_millis(500)) => continue,
};
let Some(result) = evt else { break };
match result {
Ok(event) => {
event_count += 1;
println!("event {event_count}: {event:?}");
}
Err(e) if matches!(e.errno(), Some(libc::ENOBUFS)) => {
resync_count += 1;
println!(
"\n*** ENOBUFS — events dropped; resync count = {} ***",
resync_count,
);
let snapshot: Vec<ResyncedEvent<()>> = vec![
ResyncedEvent::Marker(ResyncMarker::ResyncStart),
ResyncedEvent::Marker(ResyncMarker::ResyncEnd),
];
for s in snapshot {
println!(" resync signal: {s:?}");
}
println!("*** resumed normal event loop ***\n");
}
Err(e) => {
eprintln!("event error: {e}");
break;
}
}
}
println!(
"\ntotals: {event_count} events, {resync_count} ENOBUFS recoveries",
);
Ok(())
}