Skip to main content

disconnect_watcher/
disconnect_watcher.rs

1use std::sync::Arc;
2use std::time::Duration;
3
4use netconf_rust::{Config, Session};
5
6#[tokio::main]
7async fn main() -> netconf_rust::Result<()> {
8    let config = Config::builder()
9        .keepalive_interval(Duration::from_secs(10))
10        .keepalive_max(3)
11        .rpc_timeout(Duration::from_secs(30))
12        .connect_timeout(Duration::from_secs(10))
13        .nodelay(true)
14        .build();
15
16    let session = Arc::new(
17        Session::connect_with_config("localhost", 830, "netconf", "netconf", config).await?,
18    );
19
20    println!("Connected (session {})", session.session_id());
21
22    // Spawn a background task that fires when the session disconnects.
23    // This is the pattern you'd use in a long-running service to clean up
24    // sessions from a DashMap or similar structure.
25    let watcher_session = Arc::clone(&session);
26    let watcher = tokio::spawn(async move {
27        let reason = watcher_session.disconnected().await;
28        println!("Disconnect detected: {reason}");
29        // In a real service you'd remove the session from your map here:
30        //   sessions.remove(&uuid);
31    });
32
33    // Normal operations — the watcher runs in the background
34    let config = session
35        .get_config(netconf_rust::Datastore::Running, None)
36        .await?;
37    println!("Got config ({} bytes)", config.len());
38
39    // You can also race an RPC against disconnect using select!
40    tokio::select! {
41        result = session.get_config(netconf_rust::Datastore::Running, None) => {
42            match result {
43                Ok(data) => println!("Got config again ({} bytes)", data.len()),
44                Err(e) => eprintln!("RPC failed: {e}"),
45            }
46        }
47        reason = session.disconnected() => {
48            eprintln!("Connection lost while waiting for RPC: {reason}");
49        }
50    }
51
52    // Graceful close — the watcher will fire with DisconnectReason::Eof
53    // after the server acknowledges the close and drops the connection.
54    session.close_session().await?;
55    println!("Session closed");
56
57    // Wait for the watcher to complete
58    let _ = watcher.await;
59
60    Ok(())
61}