From ff0360ac0771a7c418f4997acada43fc426b9a29 Mon Sep 17 00:00:00 2001 From: Neshura Date: Sun, 21 Jul 2024 14:10:21 +0200 Subject: [PATCH] Implement Settings Updating inside Bot thread, Improve Status Ping behaviour --- src/bot.rs | 77 +++++++++++++++++++++++++--------------- src/main.rs | 11 +++--- src/settings/mod.rs | 20 +++++++++-- src/settings/toml/bot.rs | 10 ++++-- 4 files changed, 80 insertions(+), 38 deletions(-) diff --git a/src/bot.rs b/src/bot.rs index a8b0d9c..5ac3ee9 100644 --- a/src/bot.rs +++ b/src/bot.rs @@ -12,9 +12,10 @@ use crate::settings::{BotSettings, SeriesSettings}; pub(crate) struct Bot { settings: BotSettings, + settings_id: u16, health_signal: Arc, history: SeriesHistory, - login_time: Option> + login_time: Option>, } enum Wait { @@ -23,16 +24,26 @@ enum Wait { } impl Bot { - pub(crate) fn new(health_signal: Arc, settings: BotSettings) -> Self { + pub(crate) fn new(health_signal: Arc, settings_id: u16, settings: BotSettings) -> Self { let history: SeriesHistory = SeriesHistory::load_history(); - - Bot { health_signal, settings, history, login_time: None } + + + Bot { health_signal, settings_id, settings, history, login_time: None } } - pub(crate) fn run(&mut self, series_settings: Arc>>, update_pending: Arc) { + pub(crate) fn run( + &mut self, + series_settings: Arc>>, + bot_settings: Arc>>, + update_pending: Arc + ) { + let mut last_ping = Utc::now(); + if let Some(interval) = self.settings.status_post_interval() { + last_ping -= interval + } loop { match self.health_signal.load(Ordering::SeqCst) { HealthSignal::RequestAlive => { - //self.health_signal.store(HealthSignal::ConfirmAlive, Ordering::SeqCst); + self.health_signal.store(HealthSignal::ConfirmAlive, Ordering::SeqCst); } HealthSignal::RequestStop => { break; @@ -40,53 +51,64 @@ impl Bot { _ => {} } - while update_pending.load(Ordering::SeqCst) { + if update_pending.load(Ordering::SeqCst) { + Logging::debug("Awaiting Config Update"); sleep(Duration::milliseconds(100).to_std().unwrap()); + continue } - + + self.settings = bot_settings.read().get(&self.settings_id).unwrap().clone(); + + // perform status ping + if let Some(interval) = self.settings.status_post_interval() { + if Utc::now() + Duration::seconds(1) >= last_ping + interval { + if self.ping_status() { + last_ping = Utc::now(); + } + else { + continue + } + } + } + if let Some(login_time) = self.login_time { if Utc::now() - login_time >= Duration::minutes(60) { - self.logout(); + //self.logout(); continue } } else { - self.login(); + //self.login(); } self.history = SeriesHistory::load_history(); - - let run_start_time = Utc::now(); - self.ping_status(); series_settings.read().iter().for_each(|(id, series)| { - let new_entries = series.check(); + //let new_entries = series.check(); }); for series in series_settings.read().iter() { //series.update(&mut self.history, &lemmy, &self.settings).await; Logging::debug("Done Updating Series"); self.wait(1, Wait::Absolute); } - Logging::debug("Awaiting Timeout"); - self.wait(30, Wait::Buffer(run_start_time)); - Logging::debug("Pinging Server"); - self.ping_status(); - Logging::debug("Awaiting Timeout 2"); - self.wait(30, Wait::Absolute); } self.health_signal.store(HealthSignal::ConfirmStop, Ordering::SeqCst); } - fn ping_status(&self) { + fn ping_status(&self) -> bool { if let Some(status_url) = &self.settings.status_post_url() { - match HTTP_CLIENT.get(status_url).send() { - Ok(_) => {}, + return match HTTP_CLIENT.get(status_url).send() { + Ok(_) => { + true + }, Err(e) => { let err_msg = format!("While pinging status URL: {e}"); Logging::error(err_msg.as_str()); + false } } } + false } fn wait(&self, seconds: i64, start_time: Wait) { @@ -99,15 +121,14 @@ impl Bot { sleep(Duration::milliseconds(100).to_std().unwrap()); } } - + fn login(&mut self) { - // + todo!(); self.login_time = Some(Utc::now()); - todo!() } - + fn logout(&mut self) { self.login_time = None; - todo!() + todo!(); } } diff --git a/src/main.rs b/src/main.rs index f387202..f991833 100644 --- a/src/main.rs +++ b/src/main.rs @@ -59,18 +59,19 @@ fn main() { let mut health_signals: Vec> = vec![]; let mut update_pending: Arc = Arc::new(AtomicBool::new(false)); - - let series_settings = settings.read().series_settings().clone(); + settings.read().bot_settings().read().iter().for_each(|(id, bot_settings)| { let health_signal = Arc::new(AtomicHealthSignal::new(HealthSignal::RequestAlive)); health_signals.push(health_signal.clone()); let bot_settings = bot_settings.clone(); - let series_settings = series_settings.clone(); + let bot_id = *id; + let series_settings = settings.read().series_settings().clone(); + let bot_settings_map = settings.read().bot_settings().clone(); let update_pending = update_pending.clone(); spawn(move || { - let mut bot = Bot::new(health_signal, bot_settings); - bot.run(series_settings, update_pending); + let mut bot = Bot::new(health_signal, bot_id, bot_settings); + bot.run(series_settings, bot_settings_map, update_pending); }); }); diff --git a/src/settings/mod.rs b/src/settings/mod.rs index b88358a..b28768c 100644 --- a/src/settings/mod.rs +++ b/src/settings/mod.rs @@ -69,6 +69,12 @@ impl ApplicationSettings { } } +#[derive(Clone)] +pub struct StatusPostSettings { + url: String, + interval: Duration, +} + #[derive(Clone)] pub struct BotSettings { id: u16, @@ -76,7 +82,7 @@ pub struct BotSettings { instance: String, username: SensitiveString, password: SensitiveString, - status_post_url: Option, + status_post_settings: Option, } impl BotSettings { pub fn instance(&self) -> String { @@ -90,7 +96,17 @@ impl BotSettings { } pub fn status_post_url(&self) -> Option { - self.status_post_url.clone() + match &self.status_post_settings { + Some(settings) => Some(settings.url.clone()), + None => None + } + } + + pub fn status_post_interval(&self) -> Option { + match &self.status_post_settings { + Some(settings) => Some(settings.interval), + None => None + } } } diff --git a/src/settings/toml/bot.rs b/src/settings/toml/bot.rs index 75b06bf..034ab32 100644 --- a/src/settings/toml/bot.rs +++ b/src/settings/toml/bot.rs @@ -7,7 +7,7 @@ use crate::config::SeriesConfig; use crate::fetchers::{Fetcher, FetcherTrait}; use crate::fetchers::jnovel::JNovelFetcher; use crate::lemmy::PostType; -use crate::settings::{BotSettings, PostSettings, SeriesSettings, SettingsSource}; +use crate::settings::{BotSettings, PostSettings, SeriesSettings, SettingsSource, StatusPostSettings}; use crate::settings::toml::TomlSettings; #[derive(Serialize, Deserialize, Clone, Debug)] @@ -16,9 +16,10 @@ pub struct SingleBotTomlSettings { username: SensitiveString, password: SensitiveString, status_post_url: Option, + status_post_interval: Option, pub protected_communities: Vec, series: Vec, - fetch_interval: usize, + fetch_interval: u32, } impl SettingsSource for SingleBotTomlSettings { @@ -41,7 +42,10 @@ impl SettingsSource for SingleBotTomlSettings { instance: self.instance.clone(), username: self.username.clone(), password: self.password.clone(), - status_post_url: self.status_post_url.clone(), + status_post_settings: Some(StatusPostSettings { + url: self.status_post_url.clone().unwrap(), + interval: Duration::from_secs(self.status_post_interval.clone().unwrap() as u64) + }), }); map }