rush_sync_server/server/utils/
port.rs1use crate::core::config::Config;
3use crate::core::prelude::*;
4use std::net::TcpListener;
5use std::time::Duration;
6
7pub fn is_port_available(port: u16) -> bool {
8 match TcpListener::bind(("127.0.0.1", port)) {
9 Ok(listener) => {
10 drop(listener);
11 std::thread::sleep(Duration::from_millis(10));
12 TcpListener::bind(("127.0.0.1", port)).is_ok()
13 }
14 Err(_) => false,
15 }
16}
17
18pub fn find_next_available_port(config: &Config) -> Result<u16> {
20 let ctx = crate::server::shared::get_shared_context();
21 let servers = ctx.servers.read().unwrap();
22 let mut used_ports: Vec<u16> = servers.values().map(|s| s.port).collect();
23 used_ports.sort();
24
25 let mut candidate_port = config.server.port_range_start;
26 let max_port = config.server.port_range_end;
27
28 loop {
29 if candidate_port > max_port {
30 return Err(AppError::Validation(format!(
31 "No available ports in range {}-{}",
32 config.server.port_range_start, config.server.port_range_end
33 )));
34 }
35
36 if !used_ports.contains(&candidate_port) && is_port_available(candidate_port) {
37 return Ok(candidate_port);
38 }
39
40 candidate_port += 1;
41 }
42}
43
44pub fn find_next_available_port_legacy() -> Result<u16> {
46 let ctx = crate::server::shared::get_shared_context();
48 let servers = ctx.servers.read().unwrap();
49 let mut used_ports: Vec<u16> = servers.values().map(|s| s.port).collect();
50 used_ports.sort();
51
52 let mut candidate_port = 8080; loop {
55 if !used_ports.contains(&candidate_port) && is_port_available(candidate_port) {
56 return Ok(candidate_port);
57 }
58
59 candidate_port += 1;
60 if candidate_port > 8180 {
61 return Err(AppError::Validation(
62 "No available ports found in default range 8080-8180".to_string(),
63 ));
64 }
65 }
66}