Implement Settings Updating inside Bot thread, Improve Status Ping behaviour

This commit is contained in:
Neshura 2024-07-21 14:10:21 +02:00
parent 5976bd59a7
commit ff0360ac07
Signed by: Neshura
GPG key ID: 4E2D47B1374C297D
4 changed files with 80 additions and 38 deletions

View file

@ -12,9 +12,10 @@ use crate::settings::{BotSettings, SeriesSettings};
pub(crate) struct Bot {
settings: BotSettings,
settings_id: u16,
health_signal: Arc<AtomicHealthSignal>,
history: SeriesHistory,
login_time: Option<DateTime<Utc>>
login_time: Option<DateTime<Utc>>,
}
enum Wait {
@ -23,16 +24,26 @@ enum Wait {
}
impl Bot {
pub(crate) fn new(health_signal: Arc<AtomicHealthSignal>, settings: BotSettings) -> Self {
pub(crate) fn new(health_signal: Arc<AtomicHealthSignal>, 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<RwLock<HashMap<u16, SeriesSettings>>>,
bot_settings: Arc<RwLock<HashMap<u16, BotSettings>>>,
update_pending: Arc<AtomicBool>
) {
let mut last_ping = Utc::now();
if let Some(interval) = self.settings.status_post_interval() {
last_ping -= interval
}
pub(crate) fn run(&mut self, series_settings: Arc<RwLock<HashMap<u16, SeriesSettings>>>, update_pending: Arc<AtomicBool>) {
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) {
@ -101,13 +123,12 @@ impl Bot {
}
fn login(&mut self) {
//
todo!();
self.login_time = Some(Utc::now());
todo!()
}
fn logout(&mut self) {
self.login_time = None;
todo!()
todo!();
}
}

View file

@ -60,17 +60,18 @@ fn main() {
let mut health_signals: Vec<Arc<AtomicHealthSignal>> = vec![];
let mut update_pending: Arc<AtomicBool> = 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);
});
});

View file

@ -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<String>,
status_post_settings: Option<StatusPostSettings>,
}
impl BotSettings {
pub fn instance(&self) -> String {
@ -90,7 +96,17 @@ impl BotSettings {
}
pub fn status_post_url(&self) -> Option<String> {
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<Duration> {
match &self.status_post_settings {
Some(settings) => Some(settings.interval),
None => None
}
}
}

View file

@ -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<String>,
status_post_interval: Option<u32>,
pub protected_communities: Vec<String>,
series: Vec<SeriesConfig>,
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
}