use crate::config::Config; use crate::util::restart_service; use std::path::Path; use std::process::exit; use std::sync::mpsc; use std::thread::sleep; use std::time::Duration; use std::{fs, sync::mpsc::Receiver}; use crate::config::{CONFIG_PATH, ConfigErr, create_default_config, load_config}; pub fn move_file_to_dir( watch_path_string: &String, filename: &String, move_path_string: &String, ) -> Result<(), Box> { let move_path = Path::new(move_path_string); let watch_path = Path::new(watch_path_string); let file_path = watch_path.join(Path::new(filename)); let mut moved_file_path = move_path.join(filename); if !fs::exists(move_path)? { info!("Creating directory {}", move_path_string); fs::create_dir(move_path)?; } if fs::exists(&moved_file_path)? { moved_file_path.set_file_name(format!("{}.2", filename)); } fs::copy(&file_path, &moved_file_path)?; fs::remove_file(&file_path)?; info!("Moved file to {}", &moved_file_path.display()); Ok(()) } pub fn restart_server(service_name: String) { restart_service(service_name); } pub fn watch_files( config: Config, shutdown_rx: Receiver<()>, ) -> Result<(), Box> { loop { // Poll shutdown event. match shutdown_rx.recv_timeout(Duration::from_secs(1)) { // Break the loop either upon stop or channel disconnect Ok(_) | Err(mpsc::RecvTimeoutError::Disconnected) => { info!("Received shutdown event. Shutting down..."); break }, // Continue work if no events were received within the timeout Err(mpsc::RecvTimeoutError::Timeout) => (), }; let mut has_found = false; for file in fs::read_dir(Path::new(&config.watch_path))? { if file.is_ok() { let file_obj = file.unwrap(); let filename = file_obj.file_name().into_string().unwrap(); if filename.starts_with(&config.watch_file_prefix) && file_obj.metadata().unwrap().len() == config.watch_file_size { info!("Found file: {}. Moving file.", filename); move_file_to_dir(&config.watch_path, &filename, &config.dir)?; has_found = true; } } } if has_found { info!("Restarting target service"); restart_server(config.service_name.clone()); } sleep(Duration::from_secs(config.period as u64)); } Ok(()) } pub fn run(shutdown_rx: Receiver<()>) -> Result<(), Box> { // Step 1: Get or create config file let config_res = load_config(CONFIG_PATH); if let Err(err) = &config_res { match err { ConfigErr::NotExist => { error!("Failed to find existing config file. Create one."); match create_default_config(CONFIG_PATH) { Ok(_) => (), Err(_) => error!("Failed to create config file."), } exit(0); } ConfigErr::WriteError(e) => { error!("Failed to write config file."); error!("Message: {e}"); return Ok(()); } ConfigErr::ParsingError(e) => { error!("Failed to parse config file"); error!("Message: {e}"); return Ok(()); } ConfigErr::Unknown(e) => { error!("Unknown error"); error!("Message: {e}"); return Ok(()); } } } watch_files(config_res.unwrap(), shutdown_rx)?; Ok(()) }