writelock_issue #45

Merged
modulatingforce merged 4 commits from issue-chat-say-id-write-lock into parent-botaction-to-child-fn 2024-03-24 23:44:25 -04:00
5 changed files with 332 additions and 27 deletions
Showing only changes of commit afd7b7d387 - Show all commits

View file

@ -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<RwLock<BotInstance>>;
@ -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<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),
);
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 = {

View file

@ -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;

View file

@ -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(&params.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(&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
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 = 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 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(&params.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(&params.msg),
);
Log::flush();
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(
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(&params.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<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);
@ -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(&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;
}

View file

@ -57,8 +57,11 @@ pub async fn init(mgr: Arc<ModulesManager>) {
// 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(&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;