From aee1f80726616bf6fb885eb78698648d309d2fb8 Mon Sep 17 00:00:00 2001 From: Bulat Kurbanov Date: Mon, 22 May 2023 11:36:53 +0200 Subject: [PATCH] Add user langs cache --- src/bots/approved_bot/mod.rs | 18 +++++++++++------ src/bots/approved_bot/modules/book.rs | 20 ++++++++++++------- src/bots/approved_bot/modules/random.rs | 17 +++++++++------- src/bots/approved_bot/modules/search.rs | 14 +++++++------ src/bots/approved_bot/modules/settings.rs | 10 +++++++--- .../services/user_settings/mod.rs | 19 ++++++++++++++++-- src/bots_manager/mod.rs | 7 ++++++- 7 files changed, 73 insertions(+), 32 deletions(-) diff --git a/src/bots/approved_bot/mod.rs b/src/bots/approved_bot/mod.rs index 2f4cbd3..4a7b921 100644 --- a/src/bots/approved_bot/mod.rs +++ b/src/bots/approved_bot/mod.rs @@ -19,8 +19,13 @@ use self::{ use super::{ignore_channel_messages, BotCommands, BotHandler, bots_manager::get_manager_handler, ignore_chat_member_update}; -async fn _update_activity(me: teloxide::types::Me, user: teloxide::types::User, cache: Cache) -> Option<()> { - if cache.contains_key(&user.id) { +async fn _update_activity( + me: teloxide::types::Me, + user: teloxide::types::User, + activity_cache: Cache, + user_langs_cache: Cache>, +) -> Option<()> { + if activity_cache.contains_key(&user.id) { return None; } @@ -28,7 +33,7 @@ async fn _update_activity(me: teloxide::types::Me, user: teloxide::types::User, let mut update_result = update_user_activity(user.id).await; if update_result.is_err() { - let allowed_langs = get_user_or_default_lang_codes(user.id).await; + let allowed_langs = get_user_or_default_lang_codes(user.id, user_langs_cache.clone()).await; if create_or_update_user_settings( user.id, @@ -37,6 +42,7 @@ async fn _update_activity(me: teloxide::types::Me, user: teloxide::types::User, user.username.clone().unwrap_or("".to_string()), me.username.clone().unwrap(), allowed_langs, + user_langs_cache, ).await.is_ok() { update_result = update_user_activity(user.id).await; @@ -44,7 +50,7 @@ async fn _update_activity(me: teloxide::types::Me, user: teloxide::types::User, } if update_result.is_ok() { - cache.insert(user.id, true).await; + activity_cache.insert(user.id, true).await; } }); @@ -56,14 +62,14 @@ fn update_user_activity_handler() -> BotHandler { .branch( Update::filter_callback_query().chain(dptree::filter_map_async( |cq: CallbackQuery, bot: CacheMe>, app_state: AppState| async move { - _update_activity(bot.get_me().await.unwrap(), cq.from, app_state.user_activity_cache).await + _update_activity(bot.get_me().await.unwrap(), cq.from, app_state.user_activity_cache, app_state.user_langs_cache).await }, )), ) .branch(Update::filter_message().chain(dptree::filter_map_async( |message: Message, bot: CacheMe>, app_state: AppState| async move { match message.from() { - Some(user) => _update_activity(bot.get_me().await.unwrap(), user.clone(), app_state.user_activity_cache).await, + Some(user) => _update_activity(bot.get_me().await.unwrap(), user.clone(), app_state.user_activity_cache, app_state.user_langs_cache).await, None => None, } }, diff --git a/src/bots/approved_bot/modules/book.rs b/src/bots/approved_bot/modules/book.rs index 7fbaf55..e747e62 100644 --- a/src/bots/approved_bot/modules/book.rs +++ b/src/bots/approved_bot/modules/book.rs @@ -1,5 +1,6 @@ use std::str::FromStr; +use moka::future::Cache; use regex::Regex; use teloxide::{dispatching::UpdateFilterExt, dptree, prelude::*, adaptors::{Throttle, CacheMe}}; @@ -117,6 +118,7 @@ async fn send_book_handler( bot: CacheMe>, command: BookCommand, books_getter: fn(id: u32, page: u32, allowed_langs: Vec) -> Fut, + user_langs_cache: Cache>, ) -> crate::bots::BotHandlerInternal where T: Format + Clone, @@ -145,7 +147,7 @@ where } }; - let allowed_langs = get_user_or_default_lang_codes(user_id).await; + let allowed_langs = get_user_or_default_lang_codes(user_id, user_langs_cache).await; let items_page = match books_getter(id, 1, allowed_langs.clone()).await { Ok(v) => v, @@ -191,6 +193,7 @@ async fn send_pagination_book_handler( bot: CacheMe>, callback_data: BookCallbackData, books_getter: fn(id: u32, page: u32, allowed_langs: Vec) -> Fut, + user_langs_cache: Cache>, ) -> crate::bots::BotHandlerInternal where T: Format + Clone, @@ -217,7 +220,7 @@ where } }; - let allowed_langs = get_user_or_default_lang_codes(user_id).await; + let allowed_langs = get_user_or_default_lang_codes(user_id, user_langs_cache).await; let mut items_page = match books_getter(id, page, allowed_langs.clone()).await { Ok(v) => v, @@ -277,7 +280,7 @@ pub fn get_book_handler() -> crate::bots::BotHandler { Update::filter_message() .chain(filter_command::()) .endpoint( - |message: Message, bot: CacheMe>, command: BookCommand| async move { + |message: Message, bot: CacheMe>, command: BookCommand, user_langs_cache: Cache>| async move { match command { BookCommand::Author { .. } => { send_book_handler( @@ -285,6 +288,7 @@ pub fn get_book_handler() -> crate::bots::BotHandler { bot, command, get_author_books, + user_langs_cache ) .await } @@ -294,6 +298,7 @@ pub fn get_book_handler() -> crate::bots::BotHandler { bot, command, get_translator_books, + user_langs_cache ) .await } @@ -303,6 +308,7 @@ pub fn get_book_handler() -> crate::bots::BotHandler { bot, command, get_sequence_books, + user_langs_cache, ) .await } @@ -313,11 +319,11 @@ pub fn get_book_handler() -> crate::bots::BotHandler { .branch( Update::filter_callback_query() .chain(filter_callback_query::()) - .endpoint(|cq: CallbackQuery, bot: CacheMe>, callback_data: BookCallbackData| async move { + .endpoint(|cq: CallbackQuery, bot: CacheMe>, callback_data: BookCallbackData, user_langs_cache: Cache>| async move { match callback_data { - BookCallbackData::Author { .. } => send_pagination_book_handler(cq, bot, callback_data, get_author_books).await, - BookCallbackData::Translator { .. } => send_pagination_book_handler(cq, bot, callback_data, get_translator_books).await, - BookCallbackData::Sequence { .. } => send_pagination_book_handler(cq, bot, callback_data, get_sequence_books).await, + BookCallbackData::Author { .. } => send_pagination_book_handler(cq, bot, callback_data, get_author_books, user_langs_cache).await, + BookCallbackData::Translator { .. } => send_pagination_book_handler(cq, bot, callback_data, get_translator_books, user_langs_cache).await, + BookCallbackData::Sequence { .. } => send_pagination_book_handler(cq, bot, callback_data, get_sequence_books, user_langs_cache).await, } }), ) diff --git a/src/bots/approved_bot/modules/random.rs b/src/bots/approved_bot/modules/random.rs index 33b4ad3..ceb4056 100644 --- a/src/bots/approved_bot/modules/random.rs +++ b/src/bots/approved_bot/modules/random.rs @@ -1,3 +1,4 @@ +use moka::future::Cache; use strum_macros::{Display, EnumIter}; use teloxide::{ prelude::*, @@ -168,12 +169,13 @@ async fn get_random_item_handler( cq: CallbackQuery, bot: CacheMe>, item_getter: fn(allowed_langs: Vec) -> Fut, + user_langs_cache: Cache>, ) -> BotHandlerInternal where T: Format, Fut: std::future::Future>>, { - let allowed_langs = get_user_or_default_lang_codes(cq.from.id).await; + let allowed_langs = get_user_or_default_lang_codes(cq.from.id, user_langs_cache).await; let item = item_getter(allowed_langs).await; @@ -292,8 +294,9 @@ async fn get_random_book_by_genre( cq: CallbackQuery, bot: CacheMe>, genre_id: u32, + user_langs_cache: Cache>, ) -> BotHandlerInternal { - let allowed_langs = get_user_or_default_lang_codes(cq.from.id).await; + let allowed_langs = get_user_or_default_lang_codes(cq.from.id, user_langs_cache).await; let item = book_library::get_random_book_by_genre(allowed_langs, Some(genre_id)).await; @@ -317,14 +320,14 @@ pub fn get_random_hander() -> crate::bots::BotHandler { .branch( Update::filter_callback_query() .chain(filter_callback_query::()) - .endpoint(|cq: CallbackQuery, callback_data: RandomCallbackData, bot: CacheMe>| async move { + .endpoint(|cq: CallbackQuery, callback_data: RandomCallbackData, bot: CacheMe>, user_langs_cache: Cache>| async move { match callback_data { - RandomCallbackData::RandomBook => get_random_item_handler(cq, bot, book_library::get_random_book).await, - RandomCallbackData::RandomAuthor => get_random_item_handler(cq, bot, book_library::get_random_author).await, - RandomCallbackData::RandomSequence => get_random_item_handler(cq, bot, book_library::get_random_sequence).await, + RandomCallbackData::RandomBook => get_random_item_handler(cq, bot, book_library::get_random_book, user_langs_cache).await, + RandomCallbackData::RandomAuthor => get_random_item_handler(cq, bot, book_library::get_random_author, user_langs_cache).await, + RandomCallbackData::RandomSequence => get_random_item_handler(cq, bot, book_library::get_random_sequence, user_langs_cache).await, RandomCallbackData::RandomBookByGenreRequest => get_genre_metas_handler(cq, bot).await, RandomCallbackData::Genres { index } => get_genres_by_meta_handler(cq, bot, index).await, - RandomCallbackData::RandomBookByGenre { id } => get_random_book_by_genre(cq, bot, id).await, + RandomCallbackData::RandomBookByGenre { id } => get_random_book_by_genre(cq, bot, id, user_langs_cache).await, } }) ) diff --git a/src/bots/approved_bot/modules/search.rs b/src/bots/approved_bot/modules/search.rs index 868ea7b..0b69eb6 100644 --- a/src/bots/approved_bot/modules/search.rs +++ b/src/bots/approved_bot/modules/search.rs @@ -1,5 +1,6 @@ use std::str::FromStr; +use moka::future::Cache; use regex::Regex; use strum_macros::EnumIter; use teloxide::{ @@ -110,6 +111,7 @@ async fn generic_search_pagination_handler( bot: CacheMe>, search_data: SearchCallbackData, items_getter: fn(query: String, page: u32, allowed_langs: Vec) -> Fut, + user_langs_cache: Cache>, ) -> BotHandlerInternal where T: Format + Clone, @@ -133,7 +135,7 @@ where } }; - let allowed_langs = get_user_or_default_lang_codes(user_id).await; + let allowed_langs = get_user_or_default_lang_codes(user_id, user_langs_cache).await; let page = match search_data { SearchCallbackData::Book { page } => page, @@ -253,12 +255,12 @@ pub fn get_search_handler() -> crate::bots::BotHandler { ).branch( Update::filter_callback_query() .chain(filter_callback_query::()) - .endpoint(|cq: CallbackQuery, callback_data: SearchCallbackData, bot: CacheMe>| async move { + .endpoint(|cq: CallbackQuery, callback_data: SearchCallbackData, bot: CacheMe>, user_langs_cache: Cache>| async move { match callback_data { - SearchCallbackData::Book { .. } => generic_search_pagination_handler(cq, bot, callback_data, search_book).await, - SearchCallbackData::Authors { .. } => generic_search_pagination_handler(cq, bot, callback_data, search_author).await, - SearchCallbackData::Sequences { .. } => generic_search_pagination_handler(cq, bot, callback_data, search_sequence).await, - SearchCallbackData::Translators { .. } => generic_search_pagination_handler(cq, bot, callback_data, search_translator).await, + SearchCallbackData::Book { .. } => generic_search_pagination_handler(cq, bot, callback_data, search_book, user_langs_cache).await, + SearchCallbackData::Authors { .. } => generic_search_pagination_handler(cq, bot, callback_data, search_author, user_langs_cache).await, + SearchCallbackData::Sequences { .. } => generic_search_pagination_handler(cq, bot, callback_data, search_sequence, user_langs_cache).await, + SearchCallbackData::Translators { .. } => generic_search_pagination_handler(cq, bot, callback_data, search_translator, user_langs_cache).await, } }) ) diff --git a/src/bots/approved_bot/modules/settings.rs b/src/bots/approved_bot/modules/settings.rs index b2b30d9..037de98 100644 --- a/src/bots/approved_bot/modules/settings.rs +++ b/src/bots/approved_bot/modules/settings.rs @@ -10,6 +10,7 @@ use crate::bots::{ BotHandlerInternal, }; +use moka::future::Cache; use regex::Regex; use teloxide::{ prelude::*, @@ -118,6 +119,7 @@ async fn settings_callback_handler( bot: CacheMe>, callback_data: SettingsCallbackData, me: Me, + user_langs_cache: Cache>, ) -> BotHandlerInternal { let message = match cq.message { Some(v) => v, @@ -129,7 +131,7 @@ async fn settings_callback_handler( let user = cq.from; - let allowed_langs = get_user_or_default_lang_codes(user.id).await; + let allowed_langs = get_user_or_default_lang_codes(user.id, user_langs_cache.clone()).await; let mut allowed_langs_set: HashSet = HashSet::new(); allowed_langs.clone().into_iter().for_each(|v| { @@ -164,6 +166,7 @@ async fn settings_callback_handler( user.username.clone().unwrap_or("".to_string()), me.username.clone().unwrap(), allowed_langs_set.clone().into_iter().collect(), + user_langs_cache, ) .await { bot.send_message(user.id, "Ошибка! Попробуйте заново(").send().await?; @@ -205,8 +208,9 @@ pub fn get_settings_handler() -> crate::bots::BotHandler { |cq: CallbackQuery, bot: CacheMe>, callback_data: SettingsCallbackData, - me: Me| async move { - settings_callback_handler(cq, bot, callback_data, me).await + me: Me, + user_langs_cache: Cache>| async move { + settings_callback_handler(cq, bot, callback_data, me, user_langs_cache).await }, ), ) diff --git a/src/bots/approved_bot/services/user_settings/mod.rs b/src/bots/approved_bot/services/user_settings/mod.rs index 1f9a2ec..81f0e11 100644 --- a/src/bots/approved_bot/services/user_settings/mod.rs +++ b/src/bots/approved_bot/services/user_settings/mod.rs @@ -1,3 +1,4 @@ +use moka::future::Cache; use serde::Deserialize; use serde_json::json; use teloxide::types::UserId; @@ -38,11 +39,22 @@ pub async fn get_user_settings( Ok(response.json::().await?) } -pub async fn get_user_or_default_lang_codes(user_id: UserId) -> Vec { +pub async fn get_user_or_default_lang_codes( + user_id: UserId, + cache: Cache> +) -> Vec { + if let Some(cached_langs) = cache.get(&user_id) { + return cached_langs; + } + let default_lang_codes = vec![String::from("ru"), String::from("be"), String::from("uk")]; match get_user_settings(user_id).await { - Ok(v) => v.allowed_langs.into_iter().map(|lang| lang.code).collect(), + Ok(v) => { + let langs: Vec = v.allowed_langs.into_iter().map(|lang| lang.code).collect(); + cache.insert(user_id, langs.clone()).await; + langs + }, Err(_) => default_lang_codes, } } @@ -54,7 +66,10 @@ pub async fn create_or_update_user_settings( username: String, source: String, allowed_langs: Vec, + cache: Cache> ) -> Result> { + cache.invalidate(&user_id).await; + let body = json!({ "user_id": user_id, "last_name": last_name, diff --git a/src/bots_manager/mod.rs b/src/bots_manager/mod.rs index a0f22b8..76d569e 100644 --- a/src/bots_manager/mod.rs +++ b/src/bots_manager/mod.rs @@ -24,6 +24,7 @@ use self::bot_manager_client::get_bots; #[derive(Clone)] pub struct AppState { pub user_activity_cache: Cache, + pub user_langs_cache: Cache>, } pub struct BotsManager { @@ -41,7 +42,11 @@ impl BotsManager { user_activity_cache: Cache::builder() .time_to_live(Duration::from_secs(5 * 60)) .max_capacity(4096) - .build() + .build(), + user_langs_cache: Cache::builder() + .time_to_live(Duration::from_secs(5 * 60)) + .max_capacity(4096) + .build(), }, next_port: 8000, bot_port_map: HashMap::new(),