diff --git a/agent/src/main.rs b/agent/src/main.rs index 727579a..e816da7 100644 --- a/agent/src/main.rs +++ b/agent/src/main.rs @@ -2,6 +2,13 @@ use nanometrics_agent::{config, metrics, payload, transport}; use sysinfo::{Components, Networks, System}; use std::time::{Duration, Instant}; use std::sync::mpsc; +use std::sync::atomic::{AtomicBool, Ordering}; + +static RUNNING: AtomicBool = AtomicBool::new(true); + +extern "C" fn handle_signal(_: libc::c_int) { + RUNNING.store(false, Ordering::Relaxed); +} fn get_local_ip() -> String { use std::net::UdpSocket; @@ -49,12 +56,17 @@ fn main() { None }; + unsafe { + libc::signal(libc::SIGTERM, handle_signal as libc::sighandler_t); + libc::signal(libc::SIGINT, handle_signal as libc::sighandler_t); + } + let mut last_slow = Instant::now(); let mut last_medium = Instant::now(); let mut first_medium = true; let mut first_slow = true; - loop { + while RUNNING.load(Ordering::Relaxed) { let now = Instant::now(); while let Ok(transport::mqtt::MqttIncoming::ConfigUpdate(data)) = incoming_rx.try_recv() { @@ -134,4 +146,24 @@ fn main() { std::thread::sleep(Duration::from_secs(2)); } + + // Déconnexion propre : notifier le serveur avant de quitter + let offline = serde_json::to_string(&payload::AgentMetrics { + hostname: hostname.clone(), + ip: ip.clone(), + status: "offline".to_string(), + version: env!("CARGO_PKG_VERSION").to_string(), + ..Default::default() + }).unwrap_or_default(); + + if let Some(ref udp) = udp_sender { + udp.send(&offline); + } + if let Some(ref client) = mqtt_client { + transport::mqtt::publish_status( + client, &cfg.protocols.mqtt.topic_base, &hostname, "offline", + ); + std::thread::sleep(Duration::from_millis(200)); // laisser le temps au broker de recevoir + let _ = client.disconnect(); + } } diff --git a/agent/src/payload.rs b/agent/src/payload.rs index fca810a..4f955e0 100644 --- a/agent/src/payload.rs +++ b/agent/src/payload.rs @@ -5,6 +5,7 @@ pub struct AgentMetrics { pub hostname: String, pub ip: String, pub status: String, + #[serde(default)] pub version: String, pub cpu_percent: Option, pub memory_used: Option, diff --git a/agent/src/transport/mqtt.rs b/agent/src/transport/mqtt.rs index f293c2a..adc9648 100644 --- a/agent/src/transport/mqtt.rs +++ b/agent/src/transport/mqtt.rs @@ -78,3 +78,8 @@ pub fn publish_metrics(client: &Client, topic_base: &str, hostname: &str, json: let topic = format!("{}/{}/metrics", topic_base, hostname); let _ = client.publish(topic, QoS::AtMostOnce, false, json); } + +pub fn publish_status(client: &Client, topic_base: &str, hostname: &str, status: &str) { + let topic = format!("{}/{}/status", topic_base, hostname); + let _ = client.publish(topic, QoS::AtLeastOnce, true, status); +} diff --git a/agent/tests/payload_test.rs b/agent/tests/payload_test.rs index 711347d..98adde6 100644 --- a/agent/tests/payload_test.rs +++ b/agent/tests/payload_test.rs @@ -18,6 +18,7 @@ fn test_serialize_json_complet() { temperature: None, smart: None, status: "online".to_string(), + version: "0.0.0".to_string(), }; let json = serde_json::to_string(&m).unwrap(); assert!(json.contains("\"hostname\":\"srv-01\""));