writelock_issue

This commit is contained in:
ModulatingForce 2024-03-24 21:50:28 -04:00
parent 6deac8e6c7
commit afd7b7d387
5 changed files with 332 additions and 27 deletions

View file

@ -6,7 +6,7 @@ use tokio::sync::RwLock;
use crate::core::botinstance::BotInstance; use crate::core::botinstance::BotInstance;
use super::botmodules::{BotAction, BotModule}; use super::{botmodules::{BotAction, BotModule}, identity::ChatBadge};
pub type BotAR = Arc<RwLock<BotInstance>>; pub type BotAR = Arc<RwLock<BotInstance>>;
@ -41,6 +41,26 @@ impl ExecBodyParams {
parent_module parent_module
} }
pub fn get_sender(&self) -> String {
self.msg.sender.name.clone()
}
pub fn get_sender_chatbadge(&self) -> Option<ChatBadge> {
let mut requestor_badge_mut: Option<ChatBadge> = 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
}
} }

View file

@ -390,6 +390,12 @@ impl BotInstance {
Some(msg), 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()); const OF_CMD_CHANNEL:Channel = Channel(String::new());
@ -431,6 +437,11 @@ impl BotInstance {
return; return;
}; };
botlog::trace(
"ACQUIRING WRITE LOCK : ID",
Some("BotInstance > listener_main_prvmsg()".to_string()),
Some(msg),
);
let eval = { let eval = {

View file

@ -846,6 +846,12 @@ impl ModulesManager {
return ChangeResult::Failed("Module doesn't exist".to_string()); 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; let mut idlock = id.write().await;
@ -1028,6 +1034,13 @@ impl ModulesManager {
return ChangeResult::Failed("Module doesn't exist".to_string()); 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; let mut idlock = id.write().await;

View file

@ -12,6 +12,7 @@ use casual_logger::Log;
use rand::Rng; use rand::Rng;
use crate::core::identity::Permissible;
use crate::core::ratelimiter; use crate::core::ratelimiter;
use crate::core::ratelimiter::RateLimiter; use crate::core::ratelimiter::RateLimiter;
@ -23,6 +24,7 @@ use tokio::time::{sleep, Duration};
use super::bot_actions::ExecBodyParams; use super::bot_actions::ExecBodyParams;
use super::botmodules::BotModule; use super::botmodules::BotModule;
use super::identity;
use async_recursion::async_recursion; use async_recursion::async_recursion;
@ -34,7 +36,7 @@ pub struct Chat {
} }
#[derive(Clone)] #[derive(Clone,Debug)]
enum BotMsgType<'a> { enum BotMsgType<'a> {
SayInReplyTo(&'a PrivmsgMessage,String), SayInReplyTo(&'a PrivmsgMessage,String),
Say(String,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(&params.msg),
);
let (channel_login,mut outmsg) = match msginput.clone() { let (channel_login,mut outmsg) = match msginput.clone() {
BotMsgType::SayInReplyTo(msg, outmsg) => { BotMsgType::SayInReplyTo(msg, outmsg) => {
(msg.channel_login.clone(),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(&params.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(&params.msg),
);
Log::flush();
if rslt {
// in the case where the provided channel isn't something we're known to be connected to // in the case where the provided channel isn't something we're known to be connected to
botlog::warn( 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(&params.msg),
);
let parent_module = params.get_parent_module().await; let parent_module = params.get_parent_module().await;
// let parent_module = parent_module.clone(); // let parent_module = parent_module.clone();
let botlock = params.bot.read().await; let params_clone = params.clone();
let botclone = Arc::clone(&params_clone.bot);
let botlock = botclone.read().await;
let modmgr = Arc::clone(&botlock.botmodules); let modmgr = Arc::clone(&botlock.botmodules);
let modstatus = (*modmgr).modstatus( let modstatus = (*modmgr).modstatus(
parent_module.clone().expect("ERROR - Expected a module"), parent_module.clone().expect("ERROR - Expected a module"),
Channel(channel_login.clone()) Channel(channel_login.clone())
).await; ).await;
match modstatus { // match modstatus {
super::botmodules::StatusType::Enabled(_) => (), // super::botmodules::StatusType::Enabled(_) => (),
super::botmodules::StatusType::Disabled(_) => (), // super::botmodules::StatusType::Disabled(_) => (),
} // }
botlog::trace(
format!("BEFORE modstatus check : modstatus = {:?}",modstatus).as_str(),
Some("chat.rs > send_botmsg ".to_string()),
Some(&params.msg),
);
if let super::botmodules::StatusType::Disabled(lvl) = modstatus { if let super::botmodules::StatusType::Disabled(lvl) = modstatus {
// Note : At this point, chat was called in a channel where the parent module IS enabled // 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 type of validation is done outside of Chat()
// This though takes into account scenarios where we are targetting a different channel // 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(&params.msg),
);
Log::flush();
if let BotMsgType::SayInReplyTo(a, _) = msginput { if let BotMsgType::SayInReplyTo(a, _) = msginput {
botlog::trace(
"BEFORE potential Async recursion",
Some("chat.rs > send_botmsg ".to_string()),
Some(&params.clone().msg),
);
self.say_in_reply_to( Log::flush();
a,
format!("uuh {:?} is disabled on {} : {:?}",
parent_module.clone().unwrap(), // self.say_in_reply_to(
channel_login.clone(), // a,
lvl // format!("uuh {:?} is disabled on {} : {:?}",
), // parent_module.clone().unwrap(),
params.clone() // channel_login.clone(),
).await; // 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(&params.msg),
);
Log::flush();
} }
@ -141,6 +237,155 @@ impl Chat {
return 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<ChatBadge>,
cmdreqroles: Vec<UserRole>, // ) -> Result<Permissible,Box<dyn Error>> {
) -> (Permissible, ChangeResult) {
*/
botlog::trace(
"BEFORE Permissibility checks",
Some("chat.rs > send_botmsg ".to_string()),
Some(&params.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(&params_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(&params.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(&params.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); let rl = Arc::clone(&self.ratelimiters);
@ -222,6 +467,28 @@ impl Chat {
#[async_recursion] #[async_recursion]
pub async fn say_in_reply_to(&self, msg: &PrivmsgMessage, outmsg: String , params : ExecBodyParams) { pub async fn say_in_reply_to(&self, msg: &PrivmsgMessage, outmsg: String , params : ExecBodyParams) {
let botclone = Arc::clone(&params.bot);
let botlock = botclone.read().await;
let id = botlock.get_identity();
botlog::trace(
"ACQUIRING WRITE LOCK : ID",
Some("Chat > send_botmsg".to_string()),
Some(&params.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(&params.msg),
);
self.send_botmsg(BotMsgType::SayInReplyTo(msg, outmsg) , params).await; self.send_botmsg(BotMsgType::SayInReplyTo(msg, outmsg) , params).await;
} }

View file

@ -57,8 +57,11 @@ pub async fn init(mgr: Arc<ModulesManager>) {
// 2. Add the BotAction to ModulesManager // 2. Add the BotAction to ModulesManager
botc1.add_to_modmgr(Arc::clone(&mgr)).await; botc1.add_to_modmgr(Arc::clone(&mgr)).await;
// If enabling by defauling at instance level
mgr.set_instance_enabled(BotModule(String::from("experiments002"))).await; 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 [x] Get the parent module
*/ */
// let params_clone = Arc::clone(&params.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; let parent_module = params.get_parent_module().await;