55use  crate :: connection:: * ; 
66use  crate :: errors; 
77use  crate :: settings:: Settings ; 
8+ use  crate :: sink:: Message ; 
89use  crate :: sink:: Sink ; 
910use  crate :: sink:: kafka:: Kafka ; 
1011use  crate :: sink:: parquet:: Parquet ; 
@@ -22,44 +23,34 @@ use std::sync::Arc;
2223pub  mod  plain; 
2324pub  mod  tls; 
2425
26+ /// State entity which can be passed into connection handlers and callbacks 
27+ #[ derive( Clone ) ]  
2528pub  struct  ServerState  { 
26-     /** 
27-      * A reference to the global Settings object for all configuration information 
28-      */ 
29+     /// A reference to the global Settings object for all configuration information 
2930     pub  settings :  Arc < Settings > , 
30-     /** 
31-      * A Sender for sending statistics to the status handler 
32-      */ 
31+     /// A Sender for sending statistics to the status handler 
3332     pub  stats :  InputQueueScope , 
3433} 
3534
36- /** 
37-  * The Server trait describes the necessary functionality to implement a new hotdog backend server 
38-  * which can receive syslog messages 
39-  */ 
35+ // The Server trait describes the necessary functionality to implement a new hotdog backend server 
36+ // which can receive syslog messages 
4037#[ async_trait]  
4138pub  trait  Server  { 
42-     /** 
43-      * Bootstrap can/should be overridden by implementations which need to perform some work prior 
44-      * to the creation of the TcpListener and the incoming connection loop 
45-      */ 
39+     /// Bootstrap can/should be overridden by implementations which need to perform some work prior 
40+      /// to the creation of the TcpListener and the incoming connection loop 
4641     fn  bootstrap ( & mut  self ,  _state :  & ServerState )  -> Result < ( ) ,  errors:: HotdogError >  { 
4742        Ok ( ( ) ) 
4843    } 
4944
50-     /** 
51-      * Shutdown scan/should be overridden by implementations which need to perform some work after 
52-      * the termination of the connection accept loop 
53-      */ 
45+     /// Shutdown scan/should be overridden by implementations which need to perform some work after 
46+      /// the termination of the connection accept loop 
5447     fn  shutdown ( & self ,  _state :  & ServerState )  -> Result < ( ) ,  errors:: HotdogError >  { 
5548        Ok ( ( ) ) 
5649    } 
5750
58-     /** 
59-      * Handle a single connection 
60-      * 
61-      * The close_channel parameter must be a clone of our connection-tracking channel Sender 
62-      */ 
51+     /// Handle a single connection 
52+      /// 
53+      /// The close_channel parameter must be a clone of our connection-tracking channel Sender 
6354     fn  handle_connection ( 
6455        & self , 
6556        stream :  TcpStream , 
@@ -78,9 +69,7 @@ pub trait Server {
7869        Ok ( ( ) ) 
7970    } 
8071
81-     /** 
82-      * Accept connections on the addr 
83-      */ 
72+     /// Accept connections on the addr 
8473     async  fn  accept_loop ( 
8574        & mut  self , 
8675        addr :  & str , 
@@ -119,11 +108,29 @@ pub trait Server {
119108            smol:: spawn ( async  move  { 
120109                debug ! ( "Starting Parquet loop" ) ; 
121110                pq. runloop ( ) . await ; 
111+                 debug ! ( "Ending Parquet loop" ) ; 
112+                 std:: process:: exit ( 0 ) ; 
122113            } ) 
123114            . detach ( ) ; 
124115        } 
125116
126117        let  sender = sender. expect ( "Failed to configure a sink properly!" ) ; 
118+         use  std:: sync:: atomic:: { AtomicBool ,  Ordering } ; 
119+         let  should_exit = Arc :: new ( AtomicBool :: new ( false ) ) ; 
120+         let  se = should_exit. clone ( ) ; 
121+ 
122+         let  ctrlc_tx = sender. clone ( ) ; 
123+ 
124+         ctrlc:: set_handler ( move  || { 
125+             info ! ( "Interrupt has been received! Attempting to flush" ) ; 
126+             se. store ( true ,  Ordering :: SeqCst ) ; 
127+             let  tx = ctrlc_tx. clone ( ) ; 
128+             smol:: block_on ( async  move  { 
129+                 tx. send ( Message :: Flush  {  should_exit :  true  } ) 
130+                     . await 
131+                     . expect ( "Failed to send flush command" ) ; 
132+             } ) ; 
133+         } ) ; 
127134
128135        self . bootstrap ( & state) ?; 
129136
@@ -152,10 +159,21 @@ pub trait Server {
152159                . stats 
153160                . gauge ( status:: Stats :: ConnectionCount . into ( ) ) 
154161                . value ( conn_count) ; 
162+ 
163+             if  should_exit. load ( Ordering :: Relaxed )  { 
164+                 debug ! ( "Serve has been instructed to exit" ) ; 
165+                 break ; 
166+             } 
155167        } 
156168
157169        self . shutdown ( & state) ?; 
158170
159171        Ok ( ( ) ) 
160172    } 
161173} 
174+ 
175+ #[ cfg( test) ]  
176+ mod  tests { 
177+     #[ test]  
178+     fn  test_placholder ( )  { } 
179+ } 
0 commit comments