exit listener
This commit is contained in:
		
							
								
								
									
										43
									
								
								src/exit_listener.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								src/exit_listener.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | |||||||
|  | use std::sync::{ | ||||||
|  |     atomic::{AtomicBool, Ordering}, | ||||||
|  |     Arc, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | use tokio::{ | ||||||
|  |     self, signal, | ||||||
|  |     sync::{futures::Notified, Notify}, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | pub struct ExitListener { | ||||||
|  |     should_exit: Arc<AtomicBool>, | ||||||
|  |     notify: Arc<Notify>, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl ExitListener { | ||||||
|  |     pub fn new() -> Self { | ||||||
|  |         let this = Self { | ||||||
|  |             should_exit: Arc::new(AtomicBool::new(false)), | ||||||
|  |             notify: Arc::new(Notify::new()), | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         let should_exit = this.should_exit.clone(); | ||||||
|  |         let notify = this.notify.clone(); | ||||||
|  |  | ||||||
|  |         tokio::spawn(async move { | ||||||
|  |             signal::ctrl_c() | ||||||
|  |                 .await | ||||||
|  |                 .expect("Failed to install CTRL+C signal handler"); | ||||||
|  |             should_exit.store(true, Ordering::SeqCst); | ||||||
|  |             notify.notify_one(); | ||||||
|  |         }); | ||||||
|  |         this | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     pub fn notified(&self) -> Notified<'_> { | ||||||
|  |         self.notify.notified() | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     pub fn should_exit(&self) -> bool { | ||||||
|  |         self.should_exit.load(Ordering::SeqCst) | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -2,6 +2,7 @@ | |||||||
|  |  | ||||||
| mod cloudflare; | mod cloudflare; | ||||||
| mod config; | mod config; | ||||||
|  | mod exit_listener; | ||||||
| mod logging; | mod logging; | ||||||
| mod message_handler; | mod message_handler; | ||||||
| mod public_ip; | mod public_ip; | ||||||
| @@ -10,6 +11,7 @@ pub mod utils; | |||||||
|  |  | ||||||
| pub use cloudflare::CloudflareClient; | pub use cloudflare::CloudflareClient; | ||||||
| pub use config::{get_config_path, read_config, Config}; | pub use config::{get_config_path, read_config, Config}; | ||||||
|  | pub use exit_listener::ExitListener; | ||||||
| pub use logging::init_logger; | pub use logging::init_logger; | ||||||
| pub use message_handler::MessageHandler; | pub use message_handler::MessageHandler; | ||||||
| pub use public_ip::get_current_public_ipv4; | pub use public_ip::get_current_public_ipv4; | ||||||
|   | |||||||
							
								
								
									
										27
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								src/main.rs
									
									
									
									
									
								
							| @@ -1,11 +1,6 @@ | |||||||
| // SPDX: BSD-2-Clause | // SPDX: BSD-2-Clause | ||||||
|  |  | ||||||
| use futures::future::{self, Either}; | use futures::future::{self, Either}; | ||||||
| use std::sync::{ |  | ||||||
|     atomic::{AtomicBool, Ordering}, |  | ||||||
|     Arc, |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| use futures::stream::StreamExt; | use futures::stream::StreamExt; | ||||||
| use log::{error, info}; | use log::{error, info}; | ||||||
| use netlink_sys::{AsyncSocket, SocketAddr}; | use netlink_sys::{AsyncSocket, SocketAddr}; | ||||||
| @@ -13,10 +8,10 @@ use rtnetlink::new_connection; | |||||||
|  |  | ||||||
| use dynip_cloudflare::{ | use dynip_cloudflare::{ | ||||||
|     utils::{self, duration_to_string}, |     utils::{self, duration_to_string}, | ||||||
|     CloudflareClient, MessageHandler, MAX_ERORS_IN_ROW_DEFAULT, |     CloudflareClient, ExitListener, MessageHandler, MAX_ERORS_IN_ROW_DEFAULT, | ||||||
| }; | }; | ||||||
| use scopeguard::defer; | use scopeguard::defer; | ||||||
| use tokio::{signal, sync::Notify, time}; | use tokio::time; | ||||||
|  |  | ||||||
| const RTNLGRP_LINK: u32 = 1; | const RTNLGRP_LINK: u32 = 1; | ||||||
| const RTNLGRP_IPV4_IFADDR: u32 = 5; | const RTNLGRP_IPV4_IFADDR: u32 = 5; | ||||||
| @@ -38,19 +33,7 @@ async fn main() { | |||||||
|     defer! { |     defer! { | ||||||
|         log::logger().flush(); |         log::logger().flush(); | ||||||
|     } |     } | ||||||
|     let should_exit = Arc::new(AtomicBool::new(false)); |     let exit_listener = ExitListener::new(); | ||||||
|     let notify = Arc::new(Notify::new()); |  | ||||||
|  |  | ||||||
|     let should_exit_clone = should_exit.clone(); |  | ||||||
|     let notify_clone = notify.clone(); |  | ||||||
|  |  | ||||||
|     tokio::spawn(async move { |  | ||||||
|         signal::ctrl_c() |  | ||||||
|             .await |  | ||||||
|             .expect("Failed to install CTRL+C signal handler"); |  | ||||||
|         should_exit_clone.store(true, Ordering::SeqCst); |  | ||||||
|         notify_clone.notify_one(); |  | ||||||
|     }); |  | ||||||
|  |  | ||||||
|     let config = if let Some(aux) = utils::get_config().await { |     let config = if let Some(aux) = utils::get_config().await { | ||||||
|         aux |         aux | ||||||
| @@ -91,14 +74,14 @@ async fn main() { | |||||||
|         interval |         interval | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|     while !should_exit.load(Ordering::SeqCst) { |     while !exit_listener.should_exit() { | ||||||
|         let tick_future = match interval.as_mut() { |         let tick_future = match interval.as_mut() { | ||||||
|             Some(interval) => Either::Left(interval.tick()), |             Some(interval) => Either::Left(interval.tick()), | ||||||
|             None => Either::Right(future::pending::<tokio::time::Instant>()), |             None => Either::Right(future::pending::<tokio::time::Instant>()), | ||||||
|         }; |         }; | ||||||
|  |  | ||||||
|         tokio::select! { |         tokio::select! { | ||||||
|             _ = notify.notified() => break, |             _ = exit_listener.notified() => break, | ||||||
|             _ = tick_future => { |             _ = tick_future => { | ||||||
|                 if let Some(duration) = config.max_duration.as_ref() { |                 if let Some(duration) = config.max_duration.as_ref() { | ||||||
|                     let duration_string = duration_to_string(duration); |                     let duration_string = duration_to_string(duration); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user