@@ -8,32 +8,36 @@ use async_logger_log::Logger;
88use  log:: error; 
99use  std:: { 
1010    io:: { BufReader ,  Cursor } , 
11+     ops:: Drop , 
1112    path:: PathBuf , 
1213    str:: FromStr , 
1314    sync:: mpsc, 
1415    thread, 
16+     time:: Duration , 
1517} ; 
1618
1719use  crate :: cli_options:: * ; 
20+ use  crate :: common_constants:: ApplicationStates ; 
1821use  crate :: connection:: ConnectionState ; 
1922use  crate :: console_backend_capnp as  m; 
20- use  crate :: constants:: LOG_WRITER_BUFFER_MESSAGE_COUNT ; 
23+ use  crate :: constants:: { FETCH_MESSAGE_TIMEOUT_MS ,   LOG_WRITER_BUFFER_MESSAGE_COUNT } ; 
2124use  crate :: errors:: * ; 
2225use  crate :: log_panel:: { splitable_log_formatter,  LogLevel ,  LogPanelWriter } ; 
2326use  crate :: output:: { CsvLogging ,  SbpLogging } ; 
24- use  crate :: types:: { ClientSender ,  FlowControl ,  RealtimeDelay ,  SharedState } ; 
27+ use  crate :: types:: { ArcBool ,   ClientSender ,  FlowControl ,  RealtimeDelay ,  SharedState } ; 
2528use  crate :: utils:: { refresh_loggingbar,  refresh_navbar} ; 
2629
27- /// The backend server 
28- #[ pyclass]  
29- struct  Server  { 
30-     client_recv :  Option < mpsc:: Receiver < Vec < u8 > > > , 
31- } 
32- 
3330#[ pyclass]  
3431struct  ServerEndpoint  { 
3532    server_send :  Option < mpsc:: Sender < Vec < u8 > > > , 
3633} 
34+ impl  Drop  for  ServerEndpoint  { 
35+     fn  drop ( & mut  self )  { 
36+         if  let  Some ( sender)  = self . server_send . take ( )  { 
37+             drop ( sender) ; 
38+         } 
39+     } 
40+ } 
3741
3842#[ pymethods]  
3943impl  ServerEndpoint  { 
@@ -101,23 +105,44 @@ fn handle_cli(opt: CliOptions, connection_state: &ConnectionState, shared_state:
101105    } 
102106} 
103107
108+ /// The backend server 
109+ #[ pyclass]  
110+ struct  Server  { 
111+     client_recv :  Option < mpsc:: Receiver < Vec < u8 > > > , 
112+     is_running :  ArcBool , 
113+     handle :  Option < thread:: JoinHandle < ( ) > > , 
114+ } 
115+ impl  Drop  for  Server  { 
116+     fn  drop ( & mut  self )  { 
117+         self . is_running . set ( false ) ; 
118+ 
119+         if  let  Some ( recv)  = self . client_recv . take ( )  { 
120+             drop ( recv) ; 
121+         } 
122+     } 
123+ } 
124+ 
104125#[ pymethods]  
105126impl  Server  { 
106127    #[ new]  
107128    pub  fn  __new__ ( )  -> Self  { 
108-         Server  {  client_recv :  None  } 
129+         Server  { 
130+             client_recv :  None , 
131+             is_running :  ArcBool :: new ( ) , 
132+             handle :  None , 
133+         } 
109134    } 
110135
111136    #[ text_signature = "($self, /)" ]  
112137    pub  fn  fetch_message ( & mut  self ,  py :  Python )  -> Option < PyObject >  { 
113138        let  result = py. allow_threads ( move  || { 
114139            let  client_recv = self . client_recv . as_ref ( ) ; 
115140            if  let  Some ( client_recv)  = client_recv { 
116-                 let  buf = client_recv. recv ( ) ; 
117-                 if  let  Ok ( buf)  = buf { 
141+                 if  let  Ok ( buf)  =
142+                     client_recv. recv_timeout ( Duration :: from_millis ( FETCH_MESSAGE_TIMEOUT_MS ) ) 
143+                 { 
118144                    Some ( buf) 
119145                }  else  { 
120-                     println ! ( "error receiving message: {:?}" ,  buf) ; 
121146                    None 
122147                } 
123148            }  else  { 
@@ -156,7 +181,12 @@ impl Server {
156181        handle_cli ( opt,  & connection_state,  shared_state. clone ( ) ) ; 
157182        refresh_navbar ( & mut  client_send. clone ( ) ,  shared_state. clone ( ) ) ; 
158183        refresh_loggingbar ( & mut  client_send. clone ( ) ,  shared_state. clone ( ) ) ; 
159-         thread:: spawn ( move  || loop  { 
184+         self . is_running . set ( true ) ; 
185+         let  is_running = self . is_running . clone ( ) ; 
186+         self . handle  = Some ( thread:: spawn ( move  || loop  { 
187+             if  !is_running. get ( )  { 
188+                 break ; 
189+             } 
160190            let  buf = server_recv. recv ( ) ; 
161191            if  let  Ok ( buf)  = buf { 
162192                let  mut  buf_reader = BufReader :: new ( Cursor :: new ( buf) ) ; 
@@ -176,6 +206,19 @@ impl Server {
176206                    } 
177207                } ; 
178208                match  message { 
209+                     m:: message:: Status ( Ok ( cv_in) )  => { 
210+                         let  status_req =
211+                             cv_in. get_text ( ) . expect ( CAP_N_PROTO_DESERIALIZATION_FAILURE ) ; 
212+                         match  ApplicationStates :: from_str ( status_req)  { 
213+                             Ok ( ApplicationStates :: CLOSE )  => { 
214+                                 let  shared_state_clone = shared_state. clone ( ) ; 
215+                                 shared_state_clone. stop_server_running ( ) ; 
216+                                 is_running. set ( false ) ; 
217+                             } 
218+                             Ok ( _)  => { } 
219+                             Err ( _)  => { } 
220+                         } 
221+                     } 
179222                    m:: message:: ConnectRequest ( Ok ( conn_req) )  => { 
180223                        let  request = conn_req
181224                            . get_request ( ) 
@@ -328,7 +371,8 @@ impl Server {
328371                println ! ( "error: {:?}" ,  buf) ; 
329372                break ; 
330373            } 
331-         } ) ; 
374+         } 
375+         ) ) ; 
332376        Ok ( server_endpoint) 
333377    } 
334378} 
0 commit comments