From a1ac6dec31951550213ee9a37d881699e3b98a92 Mon Sep 17 00:00:00 2001 From: Florian Schmidt Date: Sun, 6 Oct 2024 12:41:34 +0200 Subject: [PATCH] replace signal hell with global variable --- Cargo.lock | 61 +++++++++++--------------- src/bin/mensi-telegram-bin.rs | 50 ++++++--------------- src/bin/stuwe-telegram-bin.rs | 51 ++++++---------------- src/bot_command_handlers.rs | 75 +++++--------------------------- src/bot_command_helpers.rs | 15 ++----- src/constants.rs | 8 +++- src/data_types/mod.rs | 21 --------- src/shared_main.rs | 36 ++++++++-------- src/task_scheduler_funcs.rs | 81 ++++++++++++----------------------- 9 files changed, 116 insertions(+), 282 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 671baa5..d10830e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -216,9 +216,9 @@ checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" [[package]] name = "cc" -version = "1.1.24" +version = "1.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812acba72f0a070b003d3697490d2b55b837230ae7c6c6497f05cc2ddbb8d938" +checksum = "677207f6eaec43fcfd092a718c847fc38aa261d0e19b8ef6797e0ccbe789e738" dependencies = [ "shlex", ] @@ -614,9 +614,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" dependencies = [ "futures-channel", "futures-core", @@ -629,9 +629,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", "futures-sink", @@ -639,15 +639,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-executor" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" dependencies = [ "futures-core", "futures-task", @@ -656,15 +656,15 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-macro" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", @@ -673,21 +673,21 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-channel", "futures-core", @@ -1324,12 +1324,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.20.1" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82881c4be219ab5faaf2ad5e5e5ecdff8c66bd7402ca3160975c93b24961afd1" -dependencies = [ - "portable-atomic", -] +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "openssl" @@ -1521,18 +1518,18 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.5" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +checksum = "baf123a161dde1e524adf36f90bc5d8d3462824a9c43553ad07a8183161189ec" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.5" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +checksum = "a4502d8515ca9f32f1fb543d987f63d95a14934883db45bdb48060b6b69257f8" dependencies = [ "proc-macro2", "quote", @@ -1557,12 +1554,6 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" -[[package]] -name = "portable-atomic" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" - [[package]] name = "powerfmt" version = "0.2.0" diff --git a/src/bin/mensi-telegram-bin.rs b/src/bin/mensi-telegram-bin.rs index 73cffd6..265c2cf 100644 --- a/src/bin/mensi-telegram-bin.rs +++ b/src/bin/mensi-telegram-bin.rs @@ -8,22 +8,22 @@ use stuwe_telegram_rs::bot_command_handlers::{ start_time_dialogue, subscribe, unsubscribe, }; use stuwe_telegram_rs::constants::{ - BACKEND, CD_DATA, DB_FILENAME, MENSI_DB, OLLAMA_HOST, OLLAMA_MODEL, + BACKEND, CD_DATA, DB_FILENAME, MENSI_DB, OLLAMA_HOST, OLLAMA_MODEL, USER_REGISTRATIONS, }; use stuwe_telegram_rs::data_types::{ Backend, Command, DialogueState, JobHandlerTask, JobHandlerTaskType, JobType, - QueryRegistrationType, RegistrationEntry, }; use stuwe_telegram_rs::db_operations::check_or_create_db_tables; use stuwe_telegram_rs::shared_main::callback_handler; use stuwe_telegram_rs::task_scheduler_funcs::{ - handle_add_registration_task, handle_delete_registration_task, handle_query_registration_task, - handle_update_registration_task, load_jobs_from_db, start_mensaupd_hook_and_campusdual_job, + handle_add_registration_task, handle_delete_registration_task, handle_update_registration_task, + load_jobs_from_db, start_mensaupd_hook_and_campusdual_job, }; use clap::Parser; use std::env; +use std::sync::RwLock; use teloxide::{ dispatching::{ dialogue::{self, InMemStorage}, @@ -98,7 +98,6 @@ async fn main() { let bot = Bot::new(args.token); let (jobhandler_task_tx, jobhandler_task_rx): JobHandlerTaskType = broadcast::channel(10); - let (user_registration_data_tx, _): QueryRegistrationType = broadcast::channel(10); // every user has a mensa_id, but only users with auto send have a job_uuid inside RegistrEntry { @@ -106,16 +105,9 @@ async fn main() { // there is effectively only one tx and rx, however since rx cant be passed as dptree dep (?!), // tx has to be cloned and passed to both (inside command_handler it will be resubscribed to rx) let jobhandler_task_tx = jobhandler_task_tx.clone(); - let user_registration_data_tx = user_registration_data_tx.clone(); tokio::spawn(async move { log::info!("Starting task scheduler..."); - run_task_scheduler( - bot, - jobhandler_task_tx, - jobhandler_task_rx, - user_registration_data_tx, - ) - .await; + run_task_scheduler(bot, jobhandler_task_tx, jobhandler_task_rx).await; }); } @@ -123,8 +115,7 @@ async fn main() { let command_handler_deps = dptree::deps![ InMemStorage::::new(), mensen, - jobhandler_task_tx, - user_registration_data_tx + jobhandler_task_tx ]; Dispatcher::builder(bot, schema()) .dependencies(command_handler_deps) @@ -164,13 +155,15 @@ async fn run_task_scheduler( bot: Bot, jobhandler_task_tx: broadcast::Sender, mut jobhandler_task_rx: broadcast::Receiver, - user_registration_data_tx: broadcast::Sender>, ) { let sched = JobScheduler::new().await.unwrap(); start_mensaupd_hook_and_campusdual_job(bot.clone(), &sched, jobhandler_task_tx).await; - let mut loaded_user_data = load_jobs_from_db(&bot, &sched).await; + let user_registrations = load_jobs_from_db(&bot, &sched).await; + USER_REGISTRATIONS + .set(RwLock::new(user_registrations)) + .unwrap(); // start scheduler (non blocking) sched.start().await.unwrap(); @@ -181,32 +174,15 @@ async fn run_task_scheduler( while let Ok(job_handler_task) = jobhandler_task_rx.recv().await { match job_handler_task.job_type { JobType::Register => { - handle_add_registration_task(&bot, job_handler_task, &sched, &mut loaded_user_data) - .await; + handle_add_registration_task(&bot, job_handler_task, &sched).await; } JobType::UpdateRegistration => { - handle_update_registration_task( - &bot, - job_handler_task, - &sched, - &mut loaded_user_data, - ) - .await; + handle_update_registration_task(&bot, job_handler_task, &sched).await; } JobType::DeleteRegistration => { - handle_delete_registration_task(job_handler_task, &sched, &mut loaded_user_data) - .await; - } - - JobType::QueryRegistration => { - handle_query_registration_task( - job_handler_task, - &mut loaded_user_data, - user_registration_data_tx.clone(), - ) - .await; + handle_delete_registration_task(job_handler_task, &sched).await; } JobType::BroadcastUpdate => { diff --git a/src/bin/stuwe-telegram-bin.rs b/src/bin/stuwe-telegram-bin.rs index 2a24b6f..c1590af 100644 --- a/src/bin/stuwe-telegram-bin.rs +++ b/src/bin/stuwe-telegram-bin.rs @@ -7,23 +7,22 @@ use stuwe_telegram_rs::bot_command_handlers::{ start_time_dialogue, subscribe, unsubscribe, }; use stuwe_telegram_rs::constants::{ - API_URL, BACKEND, CD_DATA, DB_FILENAME, OLLAMA_HOST, OLLAMA_MODEL, STUWE_DB, + API_URL, BACKEND, CD_DATA, DB_FILENAME, OLLAMA_HOST, OLLAMA_MODEL, STUWE_DB, USER_REGISTRATIONS, }; use stuwe_telegram_rs::data_backend::stuwe_parser::get_mensen; use stuwe_telegram_rs::data_types::{ Backend, Command, DialogueState, JobHandlerTask, JobHandlerTaskType, JobType, - QueryRegistrationType, RegistrationEntry, }; use stuwe_telegram_rs::db_operations::check_or_create_db_tables; use stuwe_telegram_rs::shared_main::callback_handler; use stuwe_telegram_rs::task_scheduler_funcs::{ handle_add_registration_task, handle_broadcast_update_task, handle_delete_registration_task, - handle_query_registration_task, handle_update_registration_task, load_jobs_from_db, - start_mensaupd_hook_and_campusdual_job, + handle_update_registration_task, load_jobs_from_db, start_mensaupd_hook_and_campusdual_job, }; use clap::Parser; use std::env; +use std::sync::RwLock; use teloxide::{ dispatching::{ dialogue::{self, InMemStorage}, @@ -107,7 +106,6 @@ async fn main() { let bot = Bot::new(args.token); let (jobhandler_task_tx, jobhandler_task_rx): JobHandlerTaskType = broadcast::channel(10); - let (user_registration_data_tx, _): QueryRegistrationType = broadcast::channel(10); // every user has a mensa_id, but only users with auto send have a job_uuid inside RegistrEntry { @@ -115,16 +113,9 @@ async fn main() { // there is effectively only one tx and rx, however since rx cant be passed as dptree dep (?!), // tx has to be cloned and passed to both (inside command_handler it will be resubscribed to rx) let jobhandler_task_tx = jobhandler_task_tx.clone(); - let user_registration_data_tx = user_registration_data_tx.clone(); tokio::spawn(async move { log::info!("Starting task scheduler..."); - run_task_scheduler( - bot, - jobhandler_task_tx, - jobhandler_task_rx, - user_registration_data_tx, - ) - .await; + run_task_scheduler(bot, jobhandler_task_tx, jobhandler_task_rx).await; }); } @@ -132,8 +123,7 @@ async fn main() { let command_handler_deps = dptree::deps![ InMemStorage::::new(), mensen, - jobhandler_task_tx, - user_registration_data_tx + jobhandler_task_tx ]; Dispatcher::builder(bot, schema()) .dependencies(command_handler_deps) @@ -173,13 +163,15 @@ async fn run_task_scheduler( bot: Bot, jobhandler_task_tx: broadcast::Sender, mut jobhandler_task_rx: broadcast::Receiver, - user_registration_data_tx: broadcast::Sender>, ) { let sched = JobScheduler::new().await.unwrap(); start_mensaupd_hook_and_campusdual_job(bot.clone(), &sched, jobhandler_task_tx.clone()).await; - let mut loaded_user_data = load_jobs_from_db(&bot, &sched).await; + let user_registrations = load_jobs_from_db(&bot, &sched).await; + USER_REGISTRATIONS + .set(RwLock::new(user_registrations)) + .unwrap(); // start scheduler (non blocking) sched.start().await.unwrap(); @@ -190,36 +182,19 @@ async fn run_task_scheduler( while let Ok(job_handler_task) = jobhandler_task_rx.recv().await { match job_handler_task.job_type { JobType::Register => { - handle_add_registration_task(&bot, job_handler_task, &sched, &mut loaded_user_data) - .await; + handle_add_registration_task(&bot, job_handler_task, &sched).await; } JobType::UpdateRegistration => { - handle_update_registration_task( - &bot, - job_handler_task, - &sched, - &mut loaded_user_data, - ) - .await; + handle_update_registration_task(&bot, job_handler_task, &sched).await; } JobType::DeleteRegistration => { - handle_delete_registration_task(job_handler_task, &sched, &mut loaded_user_data) - .await; - } - - JobType::QueryRegistration => { - handle_query_registration_task( - job_handler_task, - &mut loaded_user_data, - user_registration_data_tx.clone(), - ) - .await; + handle_delete_registration_task(job_handler_task, &sched).await; } JobType::BroadcastUpdate => { - handle_broadcast_update_task(&bot, job_handler_task, &mut loaded_user_data).await; + handle_broadcast_update_task(&bot, job_handler_task).await; } } } diff --git a/src/bot_command_handlers.rs b/src/bot_command_handlers.rs index 801c981..939816d 100644 --- a/src/bot_command_handlers.rs +++ b/src/bot_command_handlers.rs @@ -4,11 +4,11 @@ use crate::bot_command_helpers::{ use crate::constants::NO_DB_MSG; use crate::data_types::{ Command, DialogueState, DialogueType, HandlerResult, JobHandlerTask, MensaKeyboardAction, - RegistrationEntry, UnregisterTask, UpdateRegistrationTask, + UnregisterTask, UpdateRegistrationTask, }; use crate::shared_main::{ - build_meal_message_dispatcher, make_commands_keyrow, make_mensa_keyboard, make_query_data, + build_meal_message_dispatcher, get_user_registration, make_commands_keyrow, make_mensa_keyboard, }; use rand::Rng; use std::{collections::BTreeMap, time::Instant}; @@ -30,15 +30,7 @@ pub async fn invalid_cmd(bot: Bot, msg: Message) -> HandlerResult { Ok(()) } -pub async fn day_cmd( - bot: Bot, - msg: Message, - cmd: Command, - jobhandler_task_tx: broadcast::Sender, - user_registration_data_tx: broadcast::Sender>, -) -> HandlerResult { - let mut user_registration_data_rx = user_registration_data_tx.subscribe(); - +pub async fn day_cmd(bot: Bot, msg: Message, cmd: Command) -> HandlerResult { let days_forward = match cmd { Command::Heute => 0, Command::Morgen => 1, @@ -46,11 +38,7 @@ pub async fn day_cmd( _ => unreachable!(), }; - jobhandler_task_tx - .send(make_query_data(msg.chat.id.0)) - .unwrap(); - - if let Some(registration) = user_registration_data_rx.recv().await.unwrap() { + if let Some(registration) = get_user_registration(msg.chat.id.0) { let text = build_meal_message_dispatcher(days_forward, registration.mensa_id).await; let now = Instant::now(); @@ -74,32 +62,16 @@ pub async fn show_different_mensa( bot: Bot, msg: Message, mensen: BTreeMap, - jobhandler_task_tx: broadcast::Sender, - user_registration_data_tx: broadcast::Sender>, ) -> HandlerResult { - mensa_disp_or_upd( - bot, - msg, - mensen, - jobhandler_task_tx, - user_registration_data_tx, - MensaKeyboardAction::DisplayOnce, - ) - .await + mensa_disp_or_upd(bot, msg, mensen, MensaKeyboardAction::DisplayOnce).await } pub async fn subscribe( bot: Bot, msg: Message, jobhandler_task_tx: broadcast::Sender, - user_registration_data_tx: broadcast::Sender>, ) -> HandlerResult { - let mut user_registration_data_rx = user_registration_data_tx.subscribe(); - - jobhandler_task_tx - .send(make_query_data(msg.chat.id.0)) - .unwrap(); - if let Some(registration) = user_registration_data_rx.recv().await.unwrap() { + if let Some(registration) = get_user_registration(msg.chat.id.0) { if registration.job_uuid.is_some() { if rand::thread_rng().gen_range(0..10) == 0 { send_bloat_image(&bot, msg.chat.id).await; @@ -138,14 +110,8 @@ pub async fn unsubscribe( bot: Bot, msg: Message, jobhandler_task_tx: broadcast::Sender, - user_registration_data_tx: broadcast::Sender>, ) -> HandlerResult { - let mut user_registration_data_rx = user_registration_data_tx.subscribe(); - - jobhandler_task_tx - .send(make_query_data(msg.chat.id.0)) - .unwrap(); - if let Some(registration) = user_registration_data_rx.recv().await.unwrap() { + if let Some(registration) = get_user_registration(msg.chat.id.0) { if registration.job_uuid.is_none() { bot.send_message( msg.chat.id, @@ -171,22 +137,8 @@ pub async fn unsubscribe( Ok(()) } -pub async fn change_mensa( - bot: Bot, - msg: Message, - mensen: BTreeMap, - jobhandler_task_tx: broadcast::Sender, - user_registration_data_tx: broadcast::Sender>, -) -> HandlerResult { - mensa_disp_or_upd( - bot, - msg, - mensen, - jobhandler_task_tx, - user_registration_data_tx, - MensaKeyboardAction::Update, - ) - .await +pub async fn change_mensa(bot: Bot, msg: Message, mensen: BTreeMap) -> HandlerResult { + mensa_disp_or_upd(bot, msg, mensen, MensaKeyboardAction::Update).await } pub async fn start_time_dialogue( @@ -194,15 +146,8 @@ pub async fn start_time_dialogue( msg: Message, dialogue: DialogueType, jobhandler_task_tx: broadcast::Sender, - user_registration_data_tx: broadcast::Sender>, ) -> HandlerResult { - let mut user_registration_data_rx = user_registration_data_tx.subscribe(); - - jobhandler_task_tx - .send(make_query_data(msg.chat.id.0)) - .unwrap(); - - if user_registration_data_rx.recv().await.unwrap().is_none() { + if get_user_registration(msg.chat.id.0).is_none() { bot.send_message(msg.chat.id, NO_DB_MSG).await.unwrap(); dialogue.exit().await.unwrap(); return Ok(()); diff --git a/src/bot_command_helpers.rs b/src/bot_command_helpers.rs index a2dcf77..05275bd 100644 --- a/src/bot_command_helpers.rs +++ b/src/bot_command_helpers.rs @@ -1,10 +1,9 @@ use crate::constants::{NO_DB_MSG, OLLAMA_HOST, OLLAMA_MODEL}; use crate::data_types::{ - HandlerResult, JobHandlerTask, MensaKeyboardAction, ParsedTimeAndLastMsgFromDialleougueue, - RegistrationEntry, TimeParseError, + HandlerResult, MensaKeyboardAction, ParsedTimeAndLastMsgFromDialleougueue, TimeParseError, }; -use crate::shared_main::{make_mensa_keyboard, make_query_data}; +use crate::shared_main::{get_user_registration, make_mensa_keyboard}; use regex_lite::Regex; use serde::{Deserialize, Serialize}; @@ -14,22 +13,14 @@ use teloxide::types::InputFile; use std::collections::BTreeMap; use teloxide::prelude::*; -use tokio::sync::broadcast; pub async fn mensa_disp_or_upd( bot: Bot, msg: Message, mensen: BTreeMap, - jobhandler_task_tx: broadcast::Sender, - user_registration_data_tx: broadcast::Sender>, disp_or_update: MensaKeyboardAction, ) -> HandlerResult { - let mut user_registration_data_rx = user_registration_data_tx.subscribe(); - - jobhandler_task_tx - .send(make_query_data(msg.chat.id.0)) - .unwrap(); - if user_registration_data_rx.recv().await.unwrap().is_some() { + if get_user_registration(msg.chat.id.0).is_some() { let keyboard = make_mensa_keyboard(mensen, disp_or_update); bot.send_message(msg.chat.id, "Mensa auswählen:") .reply_markup(keyboard) diff --git a/src/constants.rs b/src/constants.rs index 239963c..ea8e337 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -1,8 +1,12 @@ -use std::sync::OnceLock; +use std::{ + collections::BTreeMap, + sync::{OnceLock, RwLock}, +}; -use crate::data_types::{Backend, CampusDualData}; +use crate::data_types::{Backend, CampusDualData, RegistrationEntry}; pub static API_URL: OnceLock = OnceLock::new(); +pub static USER_REGISTRATIONS: OnceLock>> = OnceLock::new(); pub const NO_DB_MSG: &str = "Bitte zuerst /start ausführen"; pub const MENSI_DB: &str = "mensimates.sqlite"; diff --git a/src/data_types/mod.rs b/src/data_types/mod.rs index 2144af5..20b1400 100644 --- a/src/data_types/mod.rs +++ b/src/data_types/mod.rs @@ -54,11 +54,6 @@ pub type JobHandlerTaskType = ( broadcast::Receiver, ); -pub type QueryRegistrationType = ( - broadcast::Sender>, - broadcast::Receiver>, -); - pub enum MensaKeyboardAction { Register, Update, @@ -70,7 +65,6 @@ pub enum MensaKeyboardAction { pub enum JobType { Register, DeleteRegistration, - QueryRegistration, UpdateRegistration, BroadcastUpdate, } @@ -117,21 +111,6 @@ impl From for JobHandlerTask { } } -pub struct QueryRegistrationTask { - pub chat_id: i64, -} -impl From for JobHandlerTask { - fn from(job: QueryRegistrationTask) -> Self { - JobHandlerTask { - job_type: JobType::QueryRegistration, - chat_id: Some(job.chat_id), - mensa_id: None, - hour: None, - minute: None, - } - } -} - pub struct UpdateRegistrationTask { pub chat_id: i64, pub mensa_id: Option, diff --git a/src/shared_main.rs b/src/shared_main.rs index ddaf8d2..ac2be64 100644 --- a/src/shared_main.rs +++ b/src/shared_main.rs @@ -15,20 +15,29 @@ use tokio_cron_scheduler::{Job, JobScheduler}; use uuid::Uuid; use crate::{ - constants::{BACKEND, NO_DB_MSG}, + constants::{BACKEND, NO_DB_MSG, USER_REGISTRATIONS}, data_backend::{mm_parser::mm_build_meal_msg, stuwe_parser::stuwe_build_meal_msg}, - data_types::{ - Backend, Command, MensaKeyboardAction, QueryRegistrationTask, RegisterTask, - UpdateRegistrationTask, - }, + data_types::{Backend, Command, MensaKeyboardAction, RegisterTask, UpdateRegistrationTask}, }; use crate::{ data_types::{JobHandlerTask, RegistrationEntry}, db_operations::update_db_row, }; -pub fn make_query_data(chat_id: i64) -> JobHandlerTask { - QueryRegistrationTask { chat_id }.into() +pub fn get_user_registration(chat_id: i64) -> Option { + let user_data = USER_REGISTRATIONS + .get() + .and_then(|data| data.read().unwrap().get(&chat_id).copied()); + user_data +} + +pub fn insert_user_registration(chat_id: i64, entry: RegistrationEntry) { + USER_REGISTRATIONS + .get() + .unwrap() + .write() + .unwrap() + .insert(chat_id, entry); } pub fn make_mensa_keyboard( @@ -125,10 +134,7 @@ pub async fn callback_handler( q: CallbackQuery, mensen: BTreeMap, jobhandler_task_tx: broadcast::Sender, - user_registration_data_tx: broadcast::Sender>, ) -> Result<(), Box> { - let mut user_registration_data_rx = user_registration_data_tx.subscribe(); - if let Some(q_data) = q.data { // acknowledge callback query to remove the loading alert bot.answer_callback_query(q.id).await?; @@ -156,8 +162,6 @@ pub async fn callback_handler( ) .await; - jobhandler_task_tx.send(make_query_data(chat.id.0)).unwrap(); - bot.send_message(chat.id, text) .parse_mode(ParseMode::MarkdownV2) .await?; @@ -228,9 +232,7 @@ pub async fn callback_handler( jobhandler_task_tx.send(task).unwrap(); } "day" => { - jobhandler_task_tx.send(make_query_data(chat.id.0)).unwrap(); - let prev_reg_opt = user_registration_data_rx.recv().await.unwrap(); - if let Some(prev_registration) = prev_reg_opt { + if let Some(registration) = get_user_registration(chat.id.0) { // start building message let now = Instant::now(); @@ -239,13 +241,11 @@ pub async fn callback_handler( [usize::try_from(days_forward).unwrap()]; let text = - build_meal_message_dispatcher(days_forward, prev_registration.mensa_id) + build_meal_message_dispatcher(days_forward, registration.mensa_id) .await; log::debug!("Build {} msg: {:.2?}", day_str, now.elapsed()); let now = Instant::now(); - jobhandler_task_tx.send(make_query_data(chat.id.0)).unwrap(); - bot.send_message(chat.id, text) .parse_mode(ParseMode::MarkdownV2) .await?; diff --git a/src/task_scheduler_funcs.rs b/src/task_scheduler_funcs.rs index cd8b773..d417b74 100644 --- a/src/task_scheduler_funcs.rs +++ b/src/task_scheduler_funcs.rs @@ -19,38 +19,39 @@ use crate::{ compare_campusdual_grades, compare_campusdual_signup_options, get_campusdual_data, save_campusdual_grades, save_campusdual_signup_options, }, - constants::{API_URL, BACKEND, CD_DATA, NO_DB_MSG}, + constants::{API_URL, BACKEND, CD_DATA, NO_DB_MSG, USER_REGISTRATIONS}, data_types::{Backend, BroadcastUpdateTask, JobHandlerTask, JobType, RegistrationEntry}, db_operations::{ get_all_user_registrations_db, init_db_record, task_db_kill_auto, update_db_row, }, - shared_main::{build_meal_message_dispatcher, load_job}, + shared_main::{ + build_meal_message_dispatcher, get_user_registration, insert_user_registration, load_job, + }, }; pub async fn handle_add_registration_task( bot: &Bot, job_handler_task: JobHandlerTask, sched: &JobScheduler, - loaded_user_data: &mut BTreeMap, ) { log::info!( "Register: {} for Mensa {}", &job_handler_task.chat_id.unwrap(), &job_handler_task.mensa_id.unwrap() ); - // creates a new row, or replaces every col with new values + // create or update row in db init_db_record(&job_handler_task).unwrap(); - if let Some(previous_registration) = loaded_user_data.get(&job_handler_task.chat_id.unwrap()) { - if let Some(uuid) = previous_registration.job_uuid { - sched.context.job_delete_tx.send(uuid).unwrap(); - }; + if let Some(uuid) = + get_user_registration(job_handler_task.chat_id.unwrap()).and_then(|reg| reg.job_uuid) + { + sched.context.job_delete_tx.send(uuid).unwrap(); } // get uuid (here guaranteed to be Some() since default is registration with job) let new_uuid = load_job(bot.clone(), sched, job_handler_task.clone()).await; // insert new job uuid - loaded_user_data.insert( + insert_user_registration( job_handler_task.chat_id.unwrap(), RegistrationEntry { job_uuid: new_uuid, @@ -65,7 +66,6 @@ pub async fn handle_update_registration_task( bot: &Bot, job_handler_task: JobHandlerTask, sched: &JobScheduler, - loaded_user_data: &mut BTreeMap, ) { if let Some(mensa) = job_handler_task.mensa_id { log::info!("{} 📌 to {}", job_handler_task.chat_id.unwrap(), mensa); @@ -79,12 +79,11 @@ pub async fn handle_update_registration_task( ); } - if let Some(previous_registration) = loaded_user_data.get(&job_handler_task.chat_id.unwrap()) { - let mensa_id = job_handler_task - .mensa_id - .unwrap_or(previous_registration.mensa_id); - let hour = job_handler_task.hour.or(previous_registration.hour); - let minute = job_handler_task.minute.or(previous_registration.minute); + // reuse old data for unset fields, as the entire row is replaced + if let Some(registration) = get_user_registration(job_handler_task.chat_id.unwrap()) { + let mensa_id = job_handler_task.mensa_id.unwrap_or(registration.mensa_id); + let hour = job_handler_task.hour.or(registration.hour); + let minute = job_handler_task.minute.or(registration.minute); let new_job_task = JobHandlerTask { job_type: JobType::UpdateRegistration, @@ -97,7 +96,7 @@ pub async fn handle_update_registration_task( let new_uuid = // new time was passed -> unload old job, load new if job_handler_task.hour.is_some() || job_handler_task.minute.is_some() || job_handler_task.mensa_id.is_some() { - if let Some(uuid) = previous_registration.job_uuid { + if let Some(uuid) = registration.job_uuid { // unload old job if exists sched.context.job_delete_tx.send(uuid).unwrap(); } @@ -109,10 +108,10 @@ pub async fn handle_update_registration_task( ).await } else { // no new time was set -> return old job uuid - previous_registration.job_uuid + registration.job_uuid }; - loaded_user_data.insert( + insert_user_registration( job_handler_task.chat_id.unwrap(), RegistrationEntry { job_uuid: new_uuid, @@ -135,31 +134,27 @@ pub async fn handle_update_registration_task( pub async fn handle_delete_registration_task( job_handler_task: JobHandlerTask, sched: &JobScheduler, - loaded_user_data: &mut BTreeMap, ) { log::info!("Unregister: {}", &job_handler_task.chat_id.unwrap()); // unregister is only invoked if existence of job is guaranteed - let previous_registration = loaded_user_data - .get(&job_handler_task.chat_id.unwrap()) - .unwrap(); + let registration = get_user_registration(job_handler_task.chat_id.unwrap()).unwrap(); // unload old job sched .context .job_delete_tx - .send(previous_registration.job_uuid.unwrap()) + .send(registration.job_uuid.unwrap()) .unwrap(); // kill uuid from this thing - loaded_user_data.insert( + insert_user_registration( job_handler_task.chat_id.unwrap(), RegistrationEntry { job_uuid: None, - mensa_id: previous_registration.mensa_id, + mensa_id: registration.mensa_id, hour: None, minute: None, - // last_markup_id, }, ); @@ -167,36 +162,14 @@ pub async fn handle_delete_registration_task( task_db_kill_auto(job_handler_task.chat_id.unwrap()).unwrap(); } -pub async fn handle_query_registration_task( - job_handler_task: JobHandlerTask, - loaded_user_data: &mut BTreeMap, - user_registration_data_tx: Sender>, -) { - // check if uuid exists - let opt_registration_entry = loaded_user_data.get(&job_handler_task.chat_id.unwrap()); - if opt_registration_entry.is_none() { - log::warn!( - "chat_id {} has no registration", - &job_handler_task.chat_id.unwrap() - ); - } - - user_registration_data_tx - .send(opt_registration_entry.copied()) - .unwrap(); -} - -pub async fn handle_broadcast_update_task( - bot: &Bot, - job_handler_task: JobHandlerTask, - loaded_user_data: &mut BTreeMap, -) { - dbg!(); +pub async fn handle_broadcast_update_task(bot: &Bot, job_handler_task: JobHandlerTask) { log::info!( "TodayMeals changed @Mensa {}", &job_handler_task.mensa_id.unwrap() ); - for (chat_id, registration_data) in loaded_user_data { + + let workaround = USER_REGISTRATIONS.get().unwrap().read().unwrap().clone(); + for (chat_id, registration_data) in workaround { let mensa_id = registration_data.mensa_id; let now = chrono::Local::now(); @@ -217,7 +190,7 @@ pub async fn handle_broadcast_update_task( build_meal_message_dispatcher(0, mensa_id).await ); - bot.send_message(ChatId(*chat_id), text) + bot.send_message(ChatId(chat_id), text) .parse_mode(ParseMode::MarkdownV2) .await .unwrap();