Skip to main content

middleware_core/discovery/static_io/
io.rs

1use std::net::UdpSocket;
2use std::path::Path;
3use std::time::Duration;
4
5use super::super::SimpleDiscovery;
6
7impl SimpleDiscovery {
8    /// Load static discovery directives from an in-memory string payload.
9    pub fn load_static_payload(&mut self, payload: &str) -> Result<usize, String> {
10        self.load_static_lines(payload.lines())
11    }
12
13    /// Broadcast current static discovery payload over UDP in one datagram.
14    pub fn broadcast_static_payload_udp(&self, destination: &str) -> Result<usize, String> {
15        let socket = UdpSocket::bind("0.0.0.0:0")
16            .map_err(|e| format!("bind udp broadcaster failed: {e}"))?;
17        socket
18            .set_broadcast(true)
19            .map_err(|e| format!("enable broadcast failed: {e}"))?;
20        let payload = self.dump_static_payload();
21        socket
22            .send_to(payload.as_bytes(), destination)
23            .map_err(|e| format!("udp broadcast failed: {e}"))
24    }
25
26    /// Receive one UDP discovery payload and merge it into this registry.
27    pub fn receive_static_payload_udp(
28        &mut self,
29        bind_addr: &str,
30        timeout: Duration,
31    ) -> Result<usize, String> {
32        let socket =
33            UdpSocket::bind(bind_addr).map_err(|e| format!("bind udp receiver failed: {e}"))?;
34        socket
35            .set_read_timeout(Some(timeout))
36            .map_err(|e| format!("set read timeout failed: {e}"))?;
37
38        let mut buf = [0u8; 65_535];
39        let (size, _) = socket
40            .recv_from(&mut buf)
41            .map_err(|e| format!("recv udp discovery payload failed: {e}"))?;
42        let payload = std::str::from_utf8(&buf[..size])
43            .map_err(|e| format!("discovery payload is not utf-8: {e}"))?;
44        self.load_static_payload(payload)
45    }
46
47    pub fn load_static_file(&mut self, path: impl AsRef<Path>) -> Result<usize, String> {
48        let content = std::fs::read_to_string(path.as_ref())
49            .map_err(|e| format!("read discovery file failed: {e}"))?;
50        self.load_static_lines(content.lines())
51    }
52}