diff --git a/noxis-rs/src/options/structs.rs b/noxis-rs/src/options/structs.rs index ef098c7..5951fd8 100644 --- a/noxis-rs/src/options/structs.rs +++ b/noxis-rs/src/options/structs.rs @@ -8,11 +8,15 @@ pub enum DependencyType { Service, } -pub struct ServiceWaitConfig { wait: u32, delay: u32} +pub enum ServiceState { + Ok, + Unavailable +} +pub struct ServiceWaitConfig(u32); impl Default for ServiceWaitConfig { fn default() -> Self { - Self { wait: 0, delay: 5 } + Self(5) } } diff --git a/noxis-rs/src/utils/services.rs b/noxis-rs/src/utils/services.rs index 2477c6d..11141a7 100644 --- a/noxis-rs/src/utils/services.rs +++ b/noxis-rs/src/utils/services.rs @@ -8,17 +8,20 @@ use tokio::time::{Duration, Instant}; use tokio::sync::mpsc::Sender as MpscSender; pub mod v2 { - use crate::options::structs::{Triggers, ProcessUnit, Events, ServiceWaitConfig}; + use crate::options::structs::{Triggers, ProcessUnit, Events, ServiceWaitConfig, ServiceState}; use super::*; - use std::collections::HashMap; + use std::collections::{HashMap, BTreeMap, VecDeque}; // type EventHandlers<'a> = Vec>>; - type EventHandlers<'a> = HashMap<&'a str, (Triggers<'a>, MpscSender>)>; + type EventHandlers<'a> = HashMap<&'a str, (Triggers<'a>, MpscSender>)>; + // type wrapper for service wait queue + type ConnectionQueue<'a> = BTreeMap, MpscSender>)>>; struct ServicesController<'a> { name : &'a str, access_url : String, + state: ServiceState, config: ServiceWaitConfig, event_registrator : EventHandlers<'a>, } @@ -27,6 +30,7 @@ pub mod v2 { ServicesController { name : "", access_url : String::new(), + state : ServiceState::Unavailable, config: ServiceWaitConfig::default(), event_registrator : EventHandlers::new(), } @@ -37,10 +41,32 @@ pub mod v2 { self.event_registrator = event_registrator; Ok(()) } + async fn check_state(&mut self) -> anyhow::Result<()> { + let mut addrs = self.access_url.to_socket_addrs()?; + if !addrs.any(|a| TcpStream::connect_timeout(&a, Duration::new(1, 0)).is_ok()) { + return Err(anyhow::Error::msg(format!("No access to service `{}`", &self.access_url))) + } + Ok(()) + } + async fn trigger_on(&mut self) {} } impl<'a> ProcessUnit<'a> for ServicesController<'a> { async fn process(&mut self) { - + // check_service(hostname, port) + let current_state = self.check_state().await; + match (&self.state, current_state) { + (ServiceState::Unavailable, Ok(_)) => { + warn!("Unreachable for connection service `{}`. Notifying {} process(es)", &self.access_url, self.event_registrator.len()); + // + self.state = ServiceState::Unavailable; + }, + (ServiceState::Ok, Err(_)) => { + warn!("Connection with `{}` service was established. Notifying {} process(es)", &self.access_url, self.event_registrator.len()); + // + self.state = ServiceState::Unavailable; + }, + _ => { /* DEAD END WITH NO INTEREST */ }, + } } } }