From afd7b7d38705588b65b2d0af3f16a493e6eff60d Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Sun, 24 Mar 2024 21:50:28 -0400 Subject: [PATCH] writelock_issue --- src/core/bot_actions.rs | 22 +- src/core/botinstance.rs | 11 + src/core/botmodules.rs | 13 + src/core/chat.rs | 301 +++++++++++++++++++++-- src/custom/experimental/experiment002.rs | 12 +- 5 files changed, 332 insertions(+), 27 deletions(-) diff --git a/src/core/bot_actions.rs b/src/core/bot_actions.rs index d2d8d25..4b17758 100644 --- a/src/core/bot_actions.rs +++ b/src/core/bot_actions.rs @@ -6,7 +6,7 @@ use tokio::sync::RwLock; use crate::core::botinstance::BotInstance; -use super::botmodules::{BotAction, BotModule}; +use super::{botmodules::{BotAction, BotModule}, identity::ChatBadge}; pub type BotAR = Arc>; @@ -41,6 +41,26 @@ impl ExecBodyParams { parent_module } + pub fn get_sender(&self) -> String { + self.msg.sender.name.clone() + } + + pub fn get_sender_chatbadge(&self) -> Option { + + let mut requestor_badge_mut: Option = None; + + for b in &self.msg.badges { + if b.name == "moderator" { + requestor_badge_mut = Some(ChatBadge::Mod); + } else if b.name == "broadcaster" { + requestor_badge_mut = Some(ChatBadge::Broadcaster); + } + } + + let requestor_badge = requestor_badge_mut; + + requestor_badge + } } diff --git a/src/core/botinstance.rs b/src/core/botinstance.rs index dc5e70b..b202e5b 100644 --- a/src/core/botinstance.rs +++ b/src/core/botinstance.rs @@ -390,6 +390,12 @@ impl BotInstance { Some(msg), ); + botlog::trace( + "ACQUIRING WRITE LOCK : ID", + Some("BotInstance > listener_main_prvmsg()".to_string()), + Some(msg), + ); + const OF_CMD_CHANNEL:Channel = Channel(String::new()); @@ -431,6 +437,11 @@ impl BotInstance { return; }; + botlog::trace( + "ACQUIRING WRITE LOCK : ID", + Some("BotInstance > listener_main_prvmsg()".to_string()), + Some(msg), + ); let eval = { diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index b173e7b..5ae8ceb 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -846,6 +846,12 @@ impl ModulesManager { return ChangeResult::Failed("Module doesn't exist".to_string()); } + botlog::trace( + "ACQUIRING WRITE LOCK : ID", + Some("ModulesManager > Exec_enable".to_string()), + None, + ); + let mut idlock = id.write().await; @@ -1028,6 +1034,13 @@ impl ModulesManager { return ChangeResult::Failed("Module doesn't exist".to_string()); } + botlog::trace( + "ACQUIRING WRITE LOCK : ID", + Some("ModulesManager > Exec_disable".to_string()), + None, + ); + + let mut idlock = id.write().await; diff --git a/src/core/chat.rs b/src/core/chat.rs index a2d5b2b..2df41db 100644 --- a/src/core/chat.rs +++ b/src/core/chat.rs @@ -12,6 +12,7 @@ use casual_logger::Log; use rand::Rng; +use crate::core::identity::Permissible; use crate::core::ratelimiter; use crate::core::ratelimiter::RateLimiter; @@ -23,6 +24,7 @@ use tokio::time::{sleep, Duration}; use super::bot_actions::ExecBodyParams; use super::botmodules::BotModule; +use super::identity; use async_recursion::async_recursion; @@ -34,7 +36,7 @@ pub struct Chat { } -#[derive(Clone)] +#[derive(Clone,Debug)] enum BotMsgType<'a> { SayInReplyTo(&'a PrivmsgMessage,String), Say(String,String), @@ -71,6 +73,13 @@ impl Chat { */ + + botlog::trace( + format!("send_bot_msg params : {:?}",msginput).as_str(), + Some("chat.rs > send_botmsg ".to_string()), + Some(¶ms.msg), + ); + let (channel_login,mut outmsg) = match msginput.clone() { BotMsgType::SayInReplyTo(msg, outmsg) => { (msg.channel_login.clone(),outmsg) @@ -80,7 +89,26 @@ impl Chat { }, }; - if self.client.get_channel_status(channel_login.clone()).await == (false,false) { + + botlog::trace( + "BEFORE GET_CHANNEL_STATUS", + Some("chat.rs > send_botmsg ".to_string()), + Some(¶ms.msg), + ); + + let rslt = self.client.get_channel_status(channel_login.clone()).await == (false,false); + + botlog::trace( + format!("GET_CHANNEL_STATUS result = {:?}",rslt).as_str(), + Some("chat.rs > send_botmsg ".to_string()), + Some(¶ms.msg), + ); + + Log::flush(); + + + + if rslt { // in the case where the provided channel isn't something we're known to be connected to botlog::warn( @@ -92,7 +120,7 @@ impl Chat { } /* - [ ] !! => 03.24 - Somewhere around here, we should be validating module for target channel + [x] !! => 03.24 - Somewhere around here, we should be validating module for target channel */ @@ -103,37 +131,105 @@ impl Chat { */ + + botlog::trace( + "BEFORE parent_module call", + Some("chat.rs > send_botmsg ".to_string()), + Some(¶ms.msg), + ); + let parent_module = params.get_parent_module().await; // let parent_module = parent_module.clone(); - let botlock = params.bot.read().await; + let params_clone = params.clone(); + let botclone = Arc::clone(¶ms_clone.bot); + let botlock = botclone.read().await; let modmgr = Arc::clone(&botlock.botmodules); let modstatus = (*modmgr).modstatus( parent_module.clone().expect("ERROR - Expected a module"), Channel(channel_login.clone()) ).await; - match modstatus { - super::botmodules::StatusType::Enabled(_) => (), - super::botmodules::StatusType::Disabled(_) => (), - } + // match modstatus { + // super::botmodules::StatusType::Enabled(_) => (), + // super::botmodules::StatusType::Disabled(_) => (), + // } + + + botlog::trace( + format!("BEFORE modstatus check : modstatus = {:?}",modstatus).as_str(), + Some("chat.rs > send_botmsg ".to_string()), + Some(¶ms.msg), + ); + + if let super::botmodules::StatusType::Disabled(lvl) = modstatus { // Note : At this point, chat was called in a channel where the parent module IS enabled // - this type of validation is done outside of Chat() // This though takes into account scenarios where we are targetting a different channel + + botlog::trace( + "BEFORE msginput check", + Some("chat.rs > send_botmsg ".to_string()), + Some(¶ms.msg), + ); + + Log::flush(); + + if let BotMsgType::SayInReplyTo(a, _) = msginput { + + botlog::trace( + "BEFORE potential Async recursion", + Some("chat.rs > send_botmsg ".to_string()), + Some(¶ms.clone().msg), + ); - self.say_in_reply_to( - a, - format!("uuh {:?} is disabled on {} : {:?}", - parent_module.clone().unwrap(), - channel_login.clone(), - lvl - ), - params.clone() - ).await; + Log::flush(); + + + // self.say_in_reply_to( + // a, + // format!("uuh {:?} is disabled on {} : {:?}", + // parent_module.clone().unwrap(), + // channel_login.clone(), + // lvl + // ), + // params.clone() + // ).await; + + let chat_clone = self.clone(); + + // tokio::spawn( async move { + // // for _ in 0..5 { + // // println!(">> Innterroutine triggered!"); + // // sleep(Duration::from_secs_f64(5.0)).await; + // // } + + // chat_clone.say_in_reply_to( + // a, + // format!("uuh {:?} is disabled on {} : {:?}", + // parent_module.clone().unwrap(), + // channel_login.clone(), + // lvl + // ), + // params.clone() + // ).await; + // } + // ); + + + botlog::trace( + "AFTER potential Async recursion", + Some("chat.rs > send_botmsg ".to_string()), + Some(¶ms.msg), + ); + + + Log::flush(); + } @@ -141,6 +237,155 @@ impl Chat { return } + + + /* + + [ ] !! => 03.24 - Would be nice if around here , validate the user has at least some special roles in target channel + - NOTE : If these need to be refined, they can be by the custom module developer at the parent calling function of say() + - This just prevents Chat from being triggered in a channel where the sending chatter does not have any special roles + + */ + + /* + + Use the following + + pub async fn can_user_run( + &mut self, + usr: String, + channelname: Channel, + chat_badge: Option, + cmdreqroles: Vec, // ) -> Result> { + ) -> (Permissible, ChangeResult) { + + */ + + botlog::trace( + "BEFORE Permissibility checks", + Some("chat.rs > send_botmsg ".to_string()), + Some(¶ms.msg), + ); + + Log::flush(); + + + const OF_CMD_CHANNEL:Channel = Channel(String::new()); + + let permissability = Permissible::Allow; + + { + + + // let id = botlock.get_identity(); + // let mut idlock = id.write().await; // <-- [ ] 03.24 - This is definitely locking it + let channel_login_clone = channel_login.clone(); + + + let spawnhandle = tokio::spawn( + async move { + let botclone = Arc::clone(¶ms_clone.bot); + let botlock = botclone.read().await; + let id = botlock.get_identity(); + + + // botlog::trace( + // "ACQUIRING WRITE LOCK : ID", + // Some("Chat > send_botmsg".to_string()), + // Some(¶ms.msg), + // ); + + + // { + // let mut idlock = id.write().await; // <-- [ ] 03.24 - This is definitely locking it + // } + + // botlog::trace( + // "ACQUIRED WRITE LOCK : ID", + // Some("Chat > send_botmsg".to_string()), + // Some(¶ms.msg), + // ); + + // let (permissability, _) = idlock + // .can_user_run( + // params.get_sender(), + // Channel(channel_login_clone), + // params.get_sender_chatbadge(), + // vec![ + // //identity::UserRole::BotAdmin, + // identity::UserRole::Mod(OF_CMD_CHANNEL), + // identity::UserRole::SupMod(OF_CMD_CHANNEL), + // identity::UserRole::Broadcaster, + // ] + // ).await; + // permissability + } + ); + + if let Ok(permissibility) = spawnhandle.await { + botlog::trace( + format!("permisibility check : {:?}",permissability).as_str(), + Some("chat.rs > send_botmsg ".to_string()), + None + ); + + } + + + } + + + + + // let permissability = { + // let id = botlock.get_identity(); + // let mut idlock = id.write().await; // <-- [ ] 03.24 - This is definitely locking it + // let (permissability, _) = idlock + // .can_user_run( + // params.get_sender(), + // Channel(channel_login.clone()), + // params.get_sender_chatbadge(), + // vec![ + // //identity::UserRole::BotAdmin, + // identity::UserRole::Mod(OF_CMD_CHANNEL), + // identity::UserRole::SupMod(OF_CMD_CHANNEL), + // identity::UserRole::Broadcaster, + // ] + // ).await; + // permissability + // }; + + // match permissability { + // Permissible::Allow => (), + // Permissible::Block => (), + // } + + botlog::trace( + format!("permisibility check : {:?}",permissability).as_str(), + Some("chat.rs > send_botmsg ".to_string()), + None, + ); + + Log::flush(); + + if let Permissible::Block = permissability { + + + if let BotMsgType::SayInReplyTo(a, _) = msginput { + + // self.say_in_reply_to( + // a, + // format!("uuh you don't have special privileges in {}", + // channel_login.clone() + // ), + // params.clone() + // ).await; + + } + return + + } + let rl = Arc::clone(&self.ratelimiters); @@ -222,6 +467,28 @@ impl Chat { #[async_recursion] pub async fn say_in_reply_to(&self, msg: &PrivmsgMessage, outmsg: String , params : ExecBodyParams) { + let botclone = Arc::clone(¶ms.bot); + let botlock = botclone.read().await; + let id = botlock.get_identity(); + + botlog::trace( + "ACQUIRING WRITE LOCK : ID", + Some("Chat > send_botmsg".to_string()), + Some(¶ms.msg), + ); + + + { + let mut idlock = id.write().await; // <-- [ ] 03.24 - This is definitely locking it + } + + botlog::trace( + "ACQUIRED WRITE LOCK : ID", + Some("Chat > send_botmsg".to_string()), + Some(¶ms.msg), + ); + + self.send_botmsg(BotMsgType::SayInReplyTo(msg, outmsg) , params).await; } diff --git a/src/custom/experimental/experiment002.rs b/src/custom/experimental/experiment002.rs index be53ffa..d657c19 100644 --- a/src/custom/experimental/experiment002.rs +++ b/src/custom/experimental/experiment002.rs @@ -57,8 +57,11 @@ pub async fn init(mgr: Arc) { // 2. Add the BotAction to ModulesManager botc1.add_to_modmgr(Arc::clone(&mgr)).await; + // If enabling by defauling at instance level mgr.set_instance_enabled(BotModule(String::from("experiments002"))).await; + // [ ] #TODO - FOR SOME REASON, IF DISABLED BY DEFAULT, IT OVERFLOWS at RUNGTIME + } @@ -79,15 +82,6 @@ async fn sayout(params : ExecBodyParams) { [x] Get the parent module */ - // let params_clone = Arc::clone(¶ms.parent_act); - // let actlock = params_clone.read().await; - // let act = &(*actlock); - // let parent_module = match act { - // BotAction::C(c) => Some(&(*c).module), - // BotAction::L(l) => Some(&(*l).module), - // _ => None, - // }; - let parent_module = params.get_parent_module().await;