files logic fixed

feature/configv2
prplV 2025-04-22 11:22:07 -04:00
parent 502ea114a6
commit c3fd0dd09f
1 changed files with 276 additions and 270 deletions

View File

@ -1,15 +1,15 @@
use crate::options::structs::{CustomError, Files}; use crate::options::structs::{CustomError, Files};
use super::prcs::{is_active, is_frozen}; use super::prcs::{is_active, is_frozen};
use inotify::{EventMask, Inotify, WatchMask}; use inotify::{EventMask, Inotify, WatchMask};
use std::borrow::BorrowMut; use std::borrow::BorrowMut;
use std::path::Path; use std::path::Path;
use std::sync::Arc; use std::sync::Arc;
use tokio::sync::mpsc; use tokio::sync::mpsc;
use tokio::sync::mpsc::Sender as MpscSender; use tokio::sync::mpsc::Sender as Sender;
use tokio::time::Duration; use tokio::time::Duration;
use crate::options::structs::Events; use crate::options::structs::Events;
pub mod v2 { pub mod v2 {
use log::{error, info, warn}; use log::{error, info, warn};
// use std::collections::HashMap; // use std::collections::HashMap;
@ -17,15 +17,17 @@ pub mod v2 {
use super::*; use super::*;
use std::{collections::HashMap, path::Path}; use std::{collections::HashMap, path::Path};
type MpscSender<'a> = Arc<Sender<Events<'a>>>;
// type EventHandlers<'a> = HashMap<service name, sender object> // type EventHandlers<'a> = HashMap<service name, sender object>
type EventHandlers<'a> = HashMap<&'a str, (Triggers<'a>, MpscSender<Events<'a>>)>; type EventHandlers<'a> = HashMap<&'a str, (Triggers<'a>, MpscSender<'a>)>;
struct FilesController<'a> { struct FilesController<'a> {
name: &'a str, name : &'a str,
path: String, path : String,
watcher: Option<Inotify>, watcher : Option<Inotify>,
// obj: Arc<Files>, // obj: Arc<Files>,
triggers: EventHandlers<'a>, triggers : EventHandlers<'a>,
code_name : String,
} }
impl<'a> FilesController<'a> { impl<'a> FilesController<'a> {
@ -35,6 +37,7 @@ pub mod v2 {
path : String::new(), path : String::new(),
watcher: None, watcher: None,
triggers, triggers,
code_name : name.to_string(),
} }
} }
pub async fn with_path(&mut self, path: impl AsRef<Path>) -> anyhow::Result<()> { pub async fn with_path(&mut self, path: impl AsRef<Path>) -> anyhow::Result<()> {
@ -48,14 +51,17 @@ pub mod v2 {
} }
} }
}; };
self.code_name = format!("{}{}", &self.path, &self.code_name);
Ok(()) Ok(())
} }
async fn trigger_on(&mut self, trigger_type: Option<FileTriggerType>) { async fn trigger_on(&'a mut self, trigger_type: Option<FileTriggerType>) {
let _ = self.triggers.iter() let _ = self.triggers.iter()
.map(|(prc_name, (triggers, channel))| async { .map(|(prc_name, (triggers, channel))| async {
let _ = channel.send({ let _ = channel.send({
match &trigger_type { match &trigger_type {
None => Events::Positive(self.name), None => {
Events::Positive(&self.code_name)
},
Some(event) => { Some(event) => {
info!("Event on file {} ({}) : {}. Notifying `{}` ...", self.name, &self.path, event, *prc_name); info!("Event on file {} ({}) : {}. Notifying `{}` ...", self.name, &self.path, event, *prc_name);
event.event_from_file_trigger_controller(self.name, triggers) event.event_from_file_trigger_controller(self.name, triggers)
@ -66,7 +72,7 @@ pub mod v2 {
} }
} }
impl<'a> ProcessUnit<'a> for FilesController<'a> { impl<'a> ProcessUnit<'a> for FilesController<'a> {
async fn process(&mut self) { async fn process(&'a mut self) {
// polling file check // polling file check
// 1) existing check // 1) existing check
if let Ok(_) = check_file(self.name, &self.path).await { if let Ok(_) = check_file(self.name, &self.path).await {
@ -108,47 +114,47 @@ pub mod v2 {
// 2) change check // 2) change check
} }
} }
} }
/// # Fn `create_watcher` /// # Fn `create_watcher`
/// ## for creating watcher on file's delete | update events /// ## for creating watcher on file's delete | update events
/// ///
/// *input* : `&str`, `&str` /// *input* : `&str`, `&str`
/// ///
/// *output* : `Err` if it cant create file watcher | `Ok(watcher)` on successfull construction /// *output* : `Err` if it cant create file watcher | `Ok(watcher)` on successfull construction
/// ///
/// *initiator* : fn `file_handler`, fn `utils::run_daemons` /// *initiator* : fn `file_handler`, fn `utils::run_daemons`
/// ///
/// *managing* : current file's name: &str, path in local storage to current file: &str /// *managing* : current file's name: &str, path in local storage to current file: &str
/// ///
/// *depends on* : - /// *depends on* : -
/// ///
pub async fn create_watcher(filename: &str, path: &str) -> anyhow::Result<Inotify> { pub async fn create_watcher(filename: &str, path: &str) -> anyhow::Result<Inotify> {
let src = format!("{}{}", path, filename); let src = format!("{}{}", path, filename);
let inotify: Inotify = Inotify::init()?; let inotify: Inotify = Inotify::init()?;
inotify.watches().add(&src, WatchMask::ALL_EVENTS)?; inotify.watches().add(&src, WatchMask::ALL_EVENTS)?;
Ok(inotify) Ok(inotify)
} }
/// # Fn `create_watcher` /// # Fn `create_watcher`
/// ## for managing processes by checking dep files' states /// ## for managing processes by checking dep files' states
/// ///
/// *input* : `&str`, `&[Files]`, `Arc<mpsc::Sender<u8>>`, `Arc<tokio::sync::Mutex<Vec<Inotify>>>` /// *input* : `&str`, `&[Files]`, `Arc<mpsc::Sender<u8>>`, `Arc<tokio::sync::Mutex<Vec<Inotify>>>`
/// ///
/// *output* : `Err` if something with dep file is wrong | `Ok(())` on successfull dep file check /// *output* : `Err` if something with dep file is wrong | `Ok(())` on successfull dep file check
/// ///
/// *initiator* : fn `utils::running_handler` /// *initiator* : fn `utils::running_handler`
/// ///
/// *managing* : current process's name: &str, list of dep files : `&[Files]`, atomic ref counter on sender main channel for current process `Arc<mpsc::Sender<u8>>`, mut list of file watchers`Arc<tokio::sync::Mutex<Vec<Inotify>>>` /// *managing* : current process's name: &str, list of dep files : `&[Files]`, atomic ref counter on sender main channel for current process `Arc<mpsc::Sender<u8>>`, mut list of file watchers`Arc<tokio::sync::Mutex<Vec<Inotify>>>`
/// ///
/// *depends on* : Files /// *depends on* : Files
/// ///
pub async fn file_handler( pub async fn file_handler(
name: &str, name: &str,
files: &[Files], files: &[Files],
tx: Arc<mpsc::Sender<u8>>, tx: Arc<mpsc::Sender<u8>>,
watchers: Arc<tokio::sync::Mutex<Vec<Inotify>>>, watchers: Arc<tokio::sync::Mutex<Vec<Inotify>>>,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
for (i, file) in files.iter().enumerate() { for (i, file) in files.iter().enumerate() {
// let src = format!("{}{}", file.src, file.filename); // let src = format!("{}{}", file.src, file.filename);
if check_file(&file.filename, &file.src).await.is_err() { if check_file(&file.filename, &file.src).await.is_err() {
@ -227,22 +233,22 @@ pub async fn file_handler(
} }
tokio::task::yield_now().await; tokio::task::yield_now().await;
Ok(()) Ok(())
} }
/// # Fn `check_file` /// # Fn `check_file`
/// ## for checking existance of current file /// ## for checking existance of current file
/// ///
/// *input* : `&str`, `&str` /// *input* : `&str`, `&str`
/// ///
/// *output* : `Ok(())` if file exists | `Err(_)` if not | panic on fs error /// *output* : `Ok(())` if file exists | `Err(_)` if not | panic on fs error
/// ///
/// *initiator* : fn `file_handler` /// *initiator* : fn `file_handler`
/// ///
/// *managing* : current file's name: `&str` and current file's path in local storage: `&str` /// *managing* : current file's name: `&str` and current file's path in local storage: `&str`
/// ///
/// *depends on* : network activity /// *depends on* : network activity
/// ///
pub async fn check_file(filename: &str, path: &str) -> Result<(), CustomError> { pub async fn check_file(filename: &str, path: &str) -> Result<(), CustomError> {
let arc_name = Arc::new(filename.to_string()); let arc_name = Arc::new(filename.to_string());
let arc_path = Arc::new(path.to_string()); let arc_path = Arc::new(path.to_string());
tokio::task::spawn_blocking(move || { tokio::task::spawn_blocking(move || {
@ -258,10 +264,10 @@ pub async fn check_file(filename: &str, path: &str) -> Result<(), CustomError> {
.unwrap_or_else(|_| { .unwrap_or_else(|_| {
panic!("Corrupted while file check process"); panic!("Corrupted while file check process");
}) })
} }
#[cfg(test)] #[cfg(test)]
mod files_unittests { mod files_unittests {
use super::*; use super::*;
#[tokio::test] #[tokio::test]
async fn try_to_create_watcher() { async fn try_to_create_watcher() {
@ -283,4 +289,4 @@ mod files_unittests {
let res = check_file("invalid-file", "/path/to/the/no/dir").await; let res = check_file("invalid-file", "/path/to/the/no/dir").await;
assert!(res.is_err()); assert!(res.is_err());
} }
} }