@@ -19,6 +19,7 @@ use shinkai_message_primitives::shinkai_utils::signatures::{
1919use std:: collections:: HashMap ;
2020use std:: error:: Error as StdError ;
2121use std:: fmt;
22+ use std:: net:: TcpListener ;
2223use std:: path:: Path ;
2324use std:: sync:: { Arc , Weak } ;
2425use std:: { env, fs} ;
@@ -49,6 +50,14 @@ impl From<Box<dyn StdError + Send + Sync>> for NodeRunnerError {
4950 }
5051}
5152
53+ /// Checks if a port is available for binding
54+ fn port_is_available ( port : u16 ) -> bool {
55+ match TcpListener :: bind ( ( "127.0.0.1" , port) ) {
56+ Ok ( _) => true ,
57+ Err ( _) => false ,
58+ }
59+ }
60+
5261pub async fn initialize_node ( ) -> Result <
5362 ( Sender < NodeCommand > , JoinHandle < ( ) > , JoinHandle < ( ) > , Weak < Mutex < Node > > ) ,
5463 Box < dyn std:: error:: Error + Send + Sync > ,
@@ -61,6 +70,42 @@ pub async fn initialize_node() -> Result<
6170 let args = parse_args ( ) ;
6271 let node_env = fetch_node_environment ( ) ;
6372
73+ // Check if required ports are available
74+ let api_port = node_env. api_listen_address . port ( ) ;
75+ let node_port = node_env. listen_address . port ( ) ;
76+ let ws_port = node_env. ws_address . map ( |addr| addr. port ( ) ) ;
77+ let https_port = node_env. api_https_listen_address . port ( ) ;
78+
79+ if !port_is_available ( api_port) {
80+ return Err ( Box :: new ( std:: io:: Error :: new (
81+ std:: io:: ErrorKind :: AddrInUse ,
82+ format ! ( "API port {} is already in use" , api_port) ,
83+ ) ) ) ;
84+ }
85+
86+ if !port_is_available ( node_port) {
87+ return Err ( Box :: new ( std:: io:: Error :: new (
88+ std:: io:: ErrorKind :: AddrInUse ,
89+ format ! ( "Node port {} is already in use" , node_port) ,
90+ ) ) ) ;
91+ }
92+
93+ if let Some ( port) = ws_port {
94+ if !port_is_available ( port) {
95+ return Err ( Box :: new ( std:: io:: Error :: new (
96+ std:: io:: ErrorKind :: AddrInUse ,
97+ format ! ( "WebSocket port {} is already in use" , port) ,
98+ ) ) ) ;
99+ }
100+ }
101+
102+ if !port_is_available ( https_port) {
103+ return Err ( Box :: new ( std:: io:: Error :: new (
104+ std:: io:: ErrorKind :: AddrInUse ,
105+ format ! ( "HTTPS port {} is already in use" , https_port) ,
106+ ) ) ) ;
107+ }
108+
64109 // TODO:
65110 // Read file encryption key from ENV variable and decrypt the secrets file
66111 // Store in memory this file encryption key, which is used to encrypt / decrypt other information
0 commit comments