xianyun_executor/
portprobe.rs1use std::net::TcpStream;
6use std::time::Duration;
7
8const PROBE_TIMEOUT: Duration = Duration::from_millis(200);
9
10pub fn in_use(address: &str) -> bool {
16 let Ok(mut addrs) = address.to_socket_addrs() else {
17 return false;
18 };
19 let Some(addr) = addrs.next() else {
20 return false;
21 };
22 TcpStream::connect_timeout(&addr, PROBE_TIMEOUT).is_ok()
23}
24
25use std::net::ToSocketAddrs;
26
27#[cfg(test)]
28mod tests {
29 use super::*;
30 use std::net::TcpListener;
31
32 #[test]
33 fn in_use_reflects_listener_lifecycle() {
34 let listener = TcpListener::bind("127.0.0.1:0").unwrap();
35 let address = listener.local_addr().unwrap().to_string();
36
37 assert!(
38 in_use(&address),
39 "port with a listener should read as in use"
40 );
41
42 drop(listener);
43
44 let mut free = false;
49 for _ in 0..50 {
50 if !in_use(&address) {
51 free = true;
52 break;
53 }
54 std::thread::sleep(std::time::Duration::from_millis(20));
55 }
56 assert!(free, "port should read as free once the listener closes");
57 }
58}