From 6c7290883f5bb09b6b2a98a6d9f8cc397ac42e1a Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Tue, 26 Mar 2024 11:29:47 -0400 Subject: [PATCH 01/33] (init) routine methods --- src/core/botmodules.rs | 126 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 124 insertions(+), 2 deletions(-) diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index c104fdd..5b725b8 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -30,9 +30,13 @@ use std::sync::Arc; use casual_logger::Log; +use chrono::DateTime; +use chrono::Duration; +use chrono::Local; use tokio::sync::RwLock; use async_trait::async_trait; +use tokio::task::JoinHandle; use crate::core::bot_actions::actions_util; use crate::core::bot_actions::ExecBodyParams; @@ -568,8 +572,126 @@ impl BotActionTrait for Listener { } } -#[derive(Debug)] -pub struct Routine {} + +enum RoutineAttr { + DelayedStart, + ScheduledStart(DateTime<Local>), // Scheduled Date (if any) after which, if not started, may trigger + LoopDuration(Duration), // How long to wait between iterations + LoopInfinitely, + RunOnce, + MaxTimeThreshold(DateTime<Local>), // DateTime after which, it will abort/cancel or stop + MaxIterations(i64), +} +/* + a Routine can be given different combinations of the above, but business logic may validate + these at Routine construction + + For example, a Routine could have the following characteristics + - DelayedStart (so it skips the first iteration) + - ScheduledStart(DateTime<Local>) - With a Start Date-Time for the first iteration to trigger + - LoopDuration(Duration) - How long to wait between iterations + + The above without any other thresholds would loop infinitely with the above characteristics + + Another example, + - LoopDuration(Duration) - How long to wait between iterations + - MaxTimeThreshold(DateTime<Local>) + - MaxIterations(i64) + + The above has thresholds , so if either are reached, it would abort/cancel or stop . Since there is no + ScheduledStart, the routine would have to be started manually elsewhere + + Another example , + - (no RoutineAttr) + + The above would only run once, and only when the Start() is called + +*/ + +// #[derive(Debug)] +pub struct Routine { + // pub name : String , + module : BotModule , // from() can determine this if passed parents_params + // pub channel : Option<Channel> , // Routines generally run by Channel ; but can be left None + channel : Channel , // Requiring some channel context + exec_body: bot_actions::actions_util::ExecBody, + parent_params : Option<ExecBodyParams> , + join_handle : Option<JoinHandle<()>> , + complete_iterations : i64 , + remaining_iterations : i64 , + start_time : Option<DateTime<Local>> , + routine_attr : Vec<RoutineAttr> , +} + + +impl Routine { + + // Constructor + pub fn from( + _module : BotModule , + _channel : Channel, + _exec_body : bot_actions::actions_util::ExecBody , + _parent_params : Option<ExecBodyParams> + ) -> Result<String,String> { + + // [ ] Validation is made against parent_params + // to ensure those params don't conflict + // conlicts would throw an error + + Err("NOT IMPLEMENTED".to_string()) + } + + pub fn change_channel( + &self, + _channel : Channel + ) -> Result<String,String> { + // [ ] Think Ideally it should try to + // change the target channel of the + // internal process too if possible? + + Err("NOT IMPLEMENTED".to_string()) + } + + + pub fn start(&self) -> Result<String,String> + { + + // [ ] Asyncio Spawn likely around here + // [ ] & Assigns self.join_handle + + Err("NOT IMPLEMENTED".to_string()) + } + + pub fn stop(&self) -> Result<String,String> + { + Err("NOT IMPLEMENTED".to_string()) + } + + pub fn restart( + &self, + _force : bool + ) -> Result<String,String> + { + // force flag aborts the routine immediately (like cancel()) + Err("NOT IMPLEMENTED".to_string()) + } + + pub fn cancel(&self) -> Result<String,String> + { + + // [ ] Likely calls abort() + // Related : + // https://docs.rs/tokio/latest/tokio/task/struct.JoinHandle.html#method.abort + + Err("NOT IMPLEMENTED".to_string()) + } + + + +} + + + type StatusdbEntry = (ModGroup, Vec<StatusType>); type ModuleActions = Vec<Arc<RwLock<BotAction>>>; From 2ba92388a276e92de220d784010d4145d014bf40 Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Tue, 26 Mar 2024 14:30:13 -0400 Subject: [PATCH 02/33] runonce implementation --- src/core/botmodules.rs | 133 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 119 insertions(+), 14 deletions(-) diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index 5b725b8..a752ad5 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -31,13 +31,16 @@ use std::sync::Arc; use casual_logger::Log; use chrono::DateTime; -use chrono::Duration; +// use chrono::Duration; use chrono::Local; use tokio::sync::RwLock; use async_trait::async_trait; use tokio::task::JoinHandle; +use tokio::time::Instant; +use tokio::time::{sleep, Duration}; + use crate::core::bot_actions::actions_util; use crate::core::bot_actions::ExecBodyParams; use crate::core::botinstance::{BotInstance, Channel,ChangeResult}; @@ -572,8 +575,9 @@ impl BotActionTrait for Listener { } } - -enum RoutineAttr { +// #[derive(Debug, PartialEq, Eq, Hash, Clone)] +#[derive(PartialEq, Eq, Hash)] +pub enum RoutineAttr { DelayedStart, ScheduledStart(DateTime<Local>), // Scheduled Date (if any) after which, if not started, may trigger LoopDuration(Duration), // How long to wait between iterations @@ -610,16 +614,17 @@ enum RoutineAttr { // #[derive(Debug)] pub struct Routine { - // pub name : String , + pub name : String , module : BotModule , // from() can determine this if passed parents_params // pub channel : Option<Channel> , // Routines generally run by Channel ; but can be left None channel : Channel , // Requiring some channel context exec_body: bot_actions::actions_util::ExecBody, - parent_params : Option<ExecBodyParams> , + // parent_params : Option<ExecBodyParams> , + parent_params : ExecBodyParams , join_handle : Option<JoinHandle<()>> , - complete_iterations : i64 , - remaining_iterations : i64 , start_time : Option<DateTime<Local>> , + complete_iterations : i64 , + remaining_iterations : Option<i64> , routine_attr : Vec<RoutineAttr> , } @@ -628,16 +633,37 @@ impl Routine { // Constructor pub fn from( - _module : BotModule , - _channel : Channel, - _exec_body : bot_actions::actions_util::ExecBody , - _parent_params : Option<ExecBodyParams> - ) -> Result<String,String> { + name : String , + module : BotModule , + channel : Channel, + routine_attr : Vec<RoutineAttr> , + exec_body : bot_actions::actions_util::ExecBody , + // parent_params : Option<ExecBodyParams> + parent_params : ExecBodyParams + // ) -> Result<String,String> { + ) -> Result<Routine,String> { // [ ] Validation is made against parent_params // to ensure those params don't conflict // conlicts would throw an error + // parent_params.unwrap(). + + if routine_attr.contains(&RoutineAttr::RunOnce) { + return Ok(Routine { + name , + module , + channel , + exec_body , + parent_params , + join_handle : None , + start_time : None , + complete_iterations : 0 , + remaining_iterations : None , + routine_attr : routine_attr + }) ; + } + Err("NOT IMPLEMENTED".to_string()) } @@ -652,16 +678,95 @@ impl Routine { Err("NOT IMPLEMENTED".to_string()) } - - pub fn start(&self) -> Result<String,String> + pub async fn start(self) -> Result<String,String> { // [ ] Asyncio Spawn likely around here // [ ] & Assigns self.join_handle + + let self_rw = Arc::new(RwLock::new(self)); + let mut self_wr_lock = self_rw.write().await; + + if self_wr_lock.routine_attr.contains(&RoutineAttr::RunOnce) { + self_wr_lock.remaining_iterations = Some(1); + + fn innerhelper(self_rw : Arc<RwLock<Routine>>) -> Option<JoinHandle<()>> { + Some( + tokio::spawn(async move { + + + let mut self_wr_lock = self_rw.write().await; + let mut remainingiter = self_wr_lock.remaining_iterations.unwrap(); + + + + botlog::trace( + format!( + "[TRACE][Routine Started] {} in {}", + self_wr_lock.name,self_wr_lock.channel.0 + ) + .as_str(), + Some(format!( + "Routine > start() > (In Tokio Spawn) > {:?}", + self_wr_lock.module + )), + Some(&self_wr_lock.parent_params.msg), + ); + + self_wr_lock.start_time = Some(chrono::offset::Local::now()); + + + // Loop iteration + while remainingiter > 1 { + + // execution body + self_wr_lock.loopbody().await; + + // end of loop iteration + remainingiter -= 1; + { + self_wr_lock.remaining_iterations = Some(remainingiter); + self_wr_lock.complete_iterations += 1; + } + + } + + botlog::trace( + format!( + "[TRACE][Routine Completed] {} in {}", + self_wr_lock.name,self_wr_lock.channel.0 + ) + .as_str(), + Some(format!( + "Routine > start() > (In Tokio Spawn) > {:?}", + self_wr_lock.module + )), + Some(&self_wr_lock.parent_params.msg), + ); + + + })) + } + + self_wr_lock.join_handle = innerhelper(self_rw.clone()) ; + return Ok("Successfully Started Routine".to_string()); + } + + + + Err("NOT IMPLEMENTED".to_string()) } + + async fn loopbody(&self) + { + (self.exec_body)( + self.parent_params.clone() + ).await; + } + pub fn stop(&self) -> Result<String,String> { Err("NOT IMPLEMENTED".to_string()) From 4e9316ad49576c820564e03b1f479b6c8f73f89c Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Tue, 26 Mar 2024 16:56:30 -0400 Subject: [PATCH 03/33] (init) experiment test module --- src/core/bot_actions.rs | 53 ++++- src/core/botmodules.rs | 89 +++++++- src/core/chat.rs | 6 +- src/custom/experimental.rs | 2 + src/custom/experimental/experiment003.rs | 277 +++++++++++++++++++++++ 5 files changed, 413 insertions(+), 14 deletions(-) create mode 100644 src/custom/experimental/experiment003.rs diff --git a/src/core/bot_actions.rs b/src/core/bot_actions.rs index 8941654..8b88c2a 100644 --- a/src/core/bot_actions.rs +++ b/src/core/bot_actions.rs @@ -5,7 +5,7 @@ use tokio::sync::RwLock; use crate::core::botinstance::BotInstance; -use super::{botmodules::{BotAction, BotModule}, identity::ChatBadge}; +use super::{botinstance::Channel, botmodules::{BotAction, BotModule}, identity::ChatBadge}; pub type BotAR = Arc<RwLock<BotInstance>>; @@ -21,24 +21,63 @@ pub struct ExecBodyParams { impl ExecBodyParams { - pub async fn get_parent_module(&self) -> Option<BotModule> { + // pub async fn get_parent_module(&self) -> Option<BotModule> { + pub async fn get_parent_module(&self) -> BotModule { let parent_act = Arc::clone(&self.parent_act); let parent_act_lock = parent_act.read().await; let act = &(*parent_act_lock); match act { BotAction::C(c) => { - let temp = c.module.clone(); - Some(temp) + // let temp = c.module.clone(); + // Some(temp) + c.module.clone() }, BotAction::L(l) => { - let temp = l.module.clone(); - Some(temp) + // let temp = l.module.clone(); + // Some(temp) + l.module.clone() }, - _ => None + BotAction::R(r) => { + // let temp = r.module.clone(); + // Some(temp) + r.module.clone() + } + // _ => None } } + pub async fn get_routine_channel(&self) -> Option<Channel> { + + // THIS IS INCORRECT - BELOW MAY BE PULLING THE PARENT BOTACTION + // NOT THE CURRENT BOT ACTION + + let parent_act = Arc::clone(&self.parent_act); + let parent_act_lock = parent_act.read().await; + let act = &(*parent_act_lock); + match act { + BotAction::C(_) => { + // let temp = c.module.clone(); + // Some(temp) + None + }, + BotAction::L(_) => { + // let temp = l.module.clone(); + // Some(temp) + // l.module.clone() + None + }, + BotAction::R(r) => { + // let temp = r.module.clone(); + // Some(temp) + Some(r.channel.clone()) + } + // _ => None + } + } + + + pub fn get_sender(&self) -> String { self.msg.sender.name.clone() } diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index a752ad5..f327266 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -615,9 +615,9 @@ pub enum RoutineAttr { // #[derive(Debug)] pub struct Routine { pub name : String , - module : BotModule , // from() can determine this if passed parents_params + pub module : BotModule , // from() can determine this if passed parents_params // pub channel : Option<Channel> , // Routines generally run by Channel ; but can be left None - channel : Channel , // Requiring some channel context + pub channel : Channel , // Requiring some channel context exec_body: bot_actions::actions_util::ExecBody, // parent_params : Option<ExecBodyParams> , parent_params : ExecBodyParams , @@ -664,6 +664,7 @@ impl Routine { }) ; } + Err("NOT IMPLEMENTED".to_string()) } @@ -685,6 +686,7 @@ impl Routine { // [ ] & Assigns self.join_handle + let self_rw = Arc::new(RwLock::new(self)); let mut self_wr_lock = self_rw.write().await; @@ -746,15 +748,31 @@ impl Routine { ); + Log::flush(); })) } self_wr_lock.join_handle = innerhelper(self_rw.clone()) ; return Ok("Successfully Started Routine".to_string()); + } + botlog::trace( + format!( + "[ERROR][Routine NOT IMPLEMENTED] {} in {}", + self_wr_lock.name,self_wr_lock.channel.0 + ) + .as_str(), + Some(format!( + "Routine > start() > (In Tokio Spawn) > {:?}", + self_wr_lock.module + )), + Some(&self_wr_lock.parent_params.msg), + ); + + Log::flush(); Err("NOT IMPLEMENTED".to_string()) } @@ -767,27 +785,88 @@ impl Routine { ).await; } - pub fn stop(&self) -> Result<String,String> + pub async fn stop(&self) -> Result<String,String> { + + + let self_rw = Arc::new(RwLock::new(self)); + let self_lock = self_rw.read().await; + + + botlog::trace( + format!( + "[ERROR][Routine NOT IMPLEMENTED] {} in {}", + self_lock.name,self_lock.channel.0 + ) + .as_str(), + Some(format!( + "Routine > start() > (In Tokio Spawn) > {:?}", + self_lock.module + )), + Some(&self_lock.parent_params.msg), + ); + + Log::flush(); + Err("NOT IMPLEMENTED".to_string()) } - pub fn restart( + pub async fn restart( &self, _force : bool ) -> Result<String,String> { // force flag aborts the routine immediately (like cancel()) + + + let self_rw = Arc::new(RwLock::new(self)); + let self_lock = self_rw.read().await; + + + botlog::trace( + format!( + "[ERROR][Routine NOT IMPLEMENTED] {} in {}", + self_lock.name,self_lock.channel.0 + ) + .as_str(), + Some(format!( + "Routine > start() > (In Tokio Spawn) > {:?}", + self_lock.module + )), + Some(&self_lock.parent_params.msg), + ); + + Log::flush(); Err("NOT IMPLEMENTED".to_string()) } - pub fn cancel(&self) -> Result<String,String> + pub async fn cancel(&self) -> Result<String,String> { // [ ] Likely calls abort() // Related : // https://docs.rs/tokio/latest/tokio/task/struct.JoinHandle.html#method.abort + + + let self_rw = Arc::new(RwLock::new(self)); + let self_lock = self_rw.read().await; + + + botlog::trace( + format!( + "[ERROR][Routine NOT IMPLEMENTED] {} in {}", + self_lock.name,self_lock.channel.0 + ) + .as_str(), + Some(format!( + "Routine > start() > (In Tokio Spawn) > {:?}", + self_lock.module + )), + Some(&self_lock.parent_params.msg), + ); + + Log::flush(); Err("NOT IMPLEMENTED".to_string()) } diff --git a/src/core/chat.rs b/src/core/chat.rs index bb938cc..d0b85e6 100644 --- a/src/core/chat.rs +++ b/src/core/chat.rs @@ -108,7 +108,8 @@ impl Chat { let botlock = botclone.read().await; let modmgr = Arc::clone(&botlock.botmodules); let modstatus = (*modmgr).modstatus( - parent_module.clone().expect("ERROR - Expected a module"), + // parent_module.clone().expect("ERROR - Expected a module"), + parent_module.clone(), Channel(channel_login.clone()) ).await; @@ -180,7 +181,8 @@ impl Chat { self.send_botmsg(BotMsgType::Notif( format!("uuh {:?} is disabled on {} : {:?}", - parent_module.clone().unwrap(), + // parent_module.clone().unwrap(), + parent_module.clone(), channel_login.clone(), lvl ), diff --git a/src/custom/experimental.rs b/src/custom/experimental.rs index 409abd1..7da2ecb 100644 --- a/src/custom/experimental.rs +++ b/src/custom/experimental.rs @@ -12,6 +12,7 @@ pub use crate::core::botmodules::ModulesManager; mod experiment001; mod experiment002; +mod experiment003; // [ ] init() function that accepts bot instance - this is passed to init() on submodules @@ -21,4 +22,5 @@ pub async fn init(mgr: Arc<ModulesManager>) { experiment001::init(Arc::clone(&mgr)).await; experiment002::init(Arc::clone(&mgr)).await; + experiment003::init(Arc::clone(&mgr)).await; } diff --git a/src/custom/experimental/experiment003.rs b/src/custom/experimental/experiment003.rs new file mode 100644 index 0000000..0bb98b9 --- /dev/null +++ b/src/custom/experimental/experiment003.rs @@ -0,0 +1,277 @@ +/* + Custom Modules - + + Usage : + [ ] within the file's init(), define BotActions & Load them into the ModulesManager + [ ] Define Execution Bodies for these BotActions + [ ] Afterwards, add the following to parent modules.rs file + - mod <modulename>; + - within init(), <modulename>::init(mgr).await + +*/ + + +const OF_CMD_CHANNEL:Channel = Channel(String::new()); + + +use casual_logger::Log; +use rand::Rng; +use std::sync::Arc; + +use crate::core::bot_actions::ExecBodyParams; +use crate::core::botinstance::Channel; +use crate::core::botlog; + +use crate::core::bot_actions::actions_util; +use crate::core::botmodules::{BotAction, BotActionTrait, BotCommand, BotModule, Listener, ModulesManager, Routine, RoutineAttr}; + +use crate::core::identity::UserRole::*; + +use tokio::time::{sleep, Duration}; + +pub async fn init(mgr: Arc<ModulesManager>) { + + // 1. Define the BotAction + let botc1 = BotCommand { + module: BotModule(String::from("experiments003")), + command: String::from("test3"), // command call name + alias: vec![], // String of alternative names + exec_body: actions_util::asyncbox(test3_body), + help: String::from("Test Command tester"), + required_roles: vec![ + BotAdmin, + Mod(OF_CMD_CHANNEL), + ], + }; + + // 2. Add the BotAction to ModulesManager + botc1.add_to_modmgr(Arc::clone(&mgr)).await; + + +} + + +async fn test3_body(params : ExecBodyParams) { + // println!("testy triggered!"); // NOTE : This test function intends to print (e.g., to stdout) at fn call + botlog::debug( + "testy triggered!", + Some("Experiments003 > test3 command body".to_string()), + Some(¶ms.msg), + ); + + /* + Test Routine Start() by : + 1. In this single exec body , create a Routine + 2. Create a Routine Execution Body + 3. Pass the Execution Body & Routine Attributes to create the Routine + 4. Start the Routine + 5. For RunOnce , we should see it only trigger once, and then complete in the logs + + */ + + // [x] Get the module from params + + let parentmodule = params.get_parent_module().await; + let channel = params.get_routine_channel().await; + let routine_attr = vec![ + RoutineAttr::RunOnce + ]; + let exec_body = actions_util::asyncbox(rtestbody); + let parent_params = params.clone(); + + async fn rtestbody(params : ExecBodyParams) { + + let bot = Arc::clone(¶ms.bot); + + let botlock = bot.read().await; + + // uses chat.say_in_reply_to() for the bot controls for messages + botlock + .botmgrs + .chat + .say_in_reply_to( + ¶ms.msg.clone(), + String::from("Inner Routine Loop Message"), + params.clone() + ).await; + } + + let a = Routine::from( + "Routine Test".to_string(), + parentmodule, + channel.unwrap(), + routine_attr, + exec_body, + parent_params + ); + + if let Ok(newr) = a { + let rslt = newr.start().await; + + + botlog::debug( + format!("TEST3_BODY RESULT : {:?}", + rslt + ).as_str(), + Some("experiment003 > test3_body".to_string()), + Some(¶ms.msg), + ); + + + let bot = Arc::clone(¶ms.bot); + + let botlock = bot.read().await; + + // uses chat.say_in_reply_to() for the bot controls for messages + botlock + .botmgrs + .chat + .say_in_reply_to( + ¶ms.msg, + format!("Routine Result : {:?}",rslt), + params.clone() + ).await; + + + } + + + + + Log::flush(); +} + + + + + +async fn good_girl(params : ExecBodyParams) { + + // [ ] Uses gen_ratio() to output bool based on a ratio probability . + // - For example gen_ratio(2,3) is 2 out of 3 or 0.67% (numerator,denomitator) + // - More Info : https://rust-random.github.io/rand/rand/trait.Rng.html#method.gen_ratio + + if params.msg.sender.name.to_lowercase() == "ModulatingForce".to_lowercase() + || params.msg.sender.name.to_lowercase() == "mzNToRi".to_lowercase() + { + botlog::debug( + "Good Girl Detected > Pausechamp", + Some("experiments > goodgirl()".to_string()), + Some(¶ms.msg), + ); + + let rollwin = rand::thread_rng().gen_ratio(1, 10); + + if rollwin { + botlog::debug( + "Oh that's a good girl!", + Some("experiments > goodgirl()".to_string()), + Some(¶ms.msg), + ); + + let bot = Arc::clone(¶ms.bot); + + + let botlock = bot.read().await; + + // uses chat.say_in_reply_to() for the bot controls for messages + botlock + .botmgrs + .chat + .say_in_reply_to( + ¶ms.msg, + String::from("GoodGirl xdd "), + params.clone() + ).await; + + + } + } +} + +async fn testy(params : ExecBodyParams) { + println!("testy triggered!"); // NOTE : This test function intends to print (e.g., to stdout) at fn call + botlog::debug( + "testy triggered!", + Some("experiments > testy()".to_string()), + Some(¶ms.msg), + ); +} + + +async fn babygirl(params : ExecBodyParams) { + + + println!("babygirl triggered!"); // NOTE : This test function intends to print (e.g., to stdout) at fn call + botlog::debug( + "babygirl triggered!", + Some("experiments > babygirl()".to_string()), + Some(¶ms.msg), + ); + + + let bot = Arc::clone(¶ms.bot); + + let botlock = bot.read().await; + + + botlock + .botmgrs + .chat + .say_in_reply_to( + ¶ms.msg, + String::from("16:13 notohh: cafdk"), + params.clone() + ).await; + + + sleep(Duration::from_secs_f64(0.5)).await; + + botlock + .botmgrs + .chat + .say_in_reply_to( + ¶ms.msg, + String::from("16:13 notohh: have fun eating princess"), + params.clone() + ).await; + + + sleep(Duration::from_secs_f64(2.0)).await; + + botlock + .botmgrs + .chat + .say_in_reply_to( + ¶ms.msg, + String::from("16:13 notohh: baby girl"), + params.clone() + ).await; + + + +} + + +async fn routinelike(params : ExecBodyParams) { + println!("routinelike triggered!"); // NOTE : This test function intends to print (e.g., to stdout) at fn call + botlog::debug( + "routinelike triggered!", + Some("experiments > routinelike()".to_string()), + Some(¶ms.msg), + ); + + // spawn an async block that runs independently from others + + tokio::spawn( async { + for _ in 0..5 { + println!(">> Innterroutine triggered!"); + sleep(Duration::from_secs_f64(5.0)).await; + } + } + ); + + // lines are executed after in conjunction to the spawn + +} + From 5249c3af250f5de7841bf2fce801e93003bf2ece Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Wed, 27 Mar 2024 01:29:09 -0400 Subject: [PATCH 04/33] smol debug in identity --- src/core/identity.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/core/identity.rs b/src/core/identity.rs index dc2da72..e1500eb 100644 --- a/src/core/identity.rs +++ b/src/core/identity.rs @@ -553,7 +553,16 @@ async fn getroles(params : ExecBodyParams) { let arg1 = argv.next(); let targetuser = match arg1 { - None => return, // exit if no arguments + None => { + + botlog::debug( + "Exittingcmd getroles - Invalid arguments ", + Some("identity.rs > init > getroles()".to_string()), + Some(¶ms.msg), + ); + return + + }, // exit if no arguments Some(arg) => arg, }; From 3f8e798050928229a00835bab807e8197c511915 Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Wed, 27 Mar 2024 01:29:25 -0400 Subject: [PATCH 05/33] (cont) routine start --- src/core/bot_actions.rs | 25 +++--- src/core/botinstance.rs | 10 +-- src/core/botmodules.rs | 99 +++++++++++++++++------- src/core/chat.rs | 2 +- src/custom/experimental/experiment003.rs | 78 ++++++++++++++++--- 5 files changed, 160 insertions(+), 54 deletions(-) diff --git a/src/core/bot_actions.rs b/src/core/bot_actions.rs index 8b88c2a..a88e5de 100644 --- a/src/core/bot_actions.rs +++ b/src/core/bot_actions.rs @@ -15,17 +15,19 @@ pub type ActAR = Arc<RwLock<BotAction>>; pub struct ExecBodyParams { pub bot : BotAR, pub msg : PrivmsgMessage, - pub parent_act : ActAR , + // pub parent_act : ActAR , + pub curr_act : ActAR , } impl ExecBodyParams { // pub async fn get_parent_module(&self) -> Option<BotModule> { - pub async fn get_parent_module(&self) -> BotModule { + // pub async fn get_parent_module(&self) -> BotModule { + pub async fn get_module(&self) -> BotModule { - let parent_act = Arc::clone(&self.parent_act); - let parent_act_lock = parent_act.read().await; + let curr_act = Arc::clone(&self.curr_act); + let parent_act_lock = curr_act.read().await; let act = &(*parent_act_lock); match act { BotAction::C(c) => { @@ -41,36 +43,37 @@ impl ExecBodyParams { BotAction::R(r) => { // let temp = r.module.clone(); // Some(temp) - r.module.clone() + r.read().await.module.clone() } // _ => None } } - pub async fn get_routine_channel(&self) -> Option<Channel> { + pub async fn get_channel(&self) -> Option<Channel> { // THIS IS INCORRECT - BELOW MAY BE PULLING THE PARENT BOTACTION // NOT THE CURRENT BOT ACTION - let parent_act = Arc::clone(&self.parent_act); - let parent_act_lock = parent_act.read().await; + + let curr_act = Arc::clone(&self.curr_act); + let parent_act_lock = curr_act.read().await; let act = &(*parent_act_lock); match act { BotAction::C(_) => { // let temp = c.module.clone(); // Some(temp) - None + Some(Channel(self.msg.channel_login.clone())) }, BotAction::L(_) => { // let temp = l.module.clone(); // Some(temp) // l.module.clone() - None + Some(Channel(self.msg.channel_login.clone())) }, BotAction::R(r) => { // let temp = r.module.clone(); // Some(temp) - Some(r.channel.clone()) + Some(r.read().await.channel.clone()) } // _ => None } diff --git a/src/core/botinstance.rs b/src/core/botinstance.rs index 07b481d..563856f 100644 --- a/src/core/botinstance.rs +++ b/src/core/botinstance.rs @@ -404,7 +404,7 @@ impl BotInstance { let params = ExecBodyParams { bot : Arc::clone(&bot), msg : (*msg).clone(), - parent_act : Arc::clone(&act_clone), + curr_act : Arc::clone(&act_clone), }; // When sending a BotMsgTypeNotif, send_botmsg does Roles related validation as required @@ -461,7 +461,7 @@ impl BotInstance { let params = ExecBodyParams { bot : Arc::clone(&bot), msg : (*msg).clone(), - parent_act : Arc::clone(&act_clone), + curr_act : Arc::clone(&act_clone), }; @@ -491,7 +491,7 @@ impl BotInstance { let params = ExecBodyParams { bot : Arc::clone(&bot), msg : (*msg).clone(), - parent_act : Arc::clone(&act_clone), + curr_act : Arc::clone(&act_clone), }; @@ -516,7 +516,7 @@ impl BotInstance { c.execute(ExecBodyParams { bot : a, msg : msg.clone() , - parent_act : Arc::clone(&act_clone), + curr_act : Arc::clone(&act_clone), }).await; botlog::trace( @@ -564,7 +564,7 @@ impl BotInstance { l.execute(ExecBodyParams { bot : a, msg : msg.clone() , - parent_act : Arc::clone(&act_clone), + curr_act : Arc::clone(&act_clone), } ).await; } diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index f327266..34c6b02 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -469,7 +469,8 @@ pub enum StatusType { pub enum BotAction { C(BotCommand), L(Listener), - R(Routine), + // R(Routine), + R(Arc<RwLock<Routine>>), } impl BotAction { @@ -621,7 +622,7 @@ pub struct Routine { exec_body: bot_actions::actions_util::ExecBody, // parent_params : Option<ExecBodyParams> , parent_params : ExecBodyParams , - join_handle : Option<JoinHandle<()>> , + pub join_handle : Option<JoinHandle<()>> , start_time : Option<DateTime<Local>> , complete_iterations : i64 , remaining_iterations : Option<i64> , @@ -641,7 +642,11 @@ impl Routine { // parent_params : Option<ExecBodyParams> parent_params : ExecBodyParams // ) -> Result<String,String> { - ) -> Result<Routine,String> { + // ) -> Result<Routine,String> { + ) -> Result< + Arc<RwLock<Routine>>, + String + > { // [ ] Validation is made against parent_params // to ensure those params don't conflict @@ -650,7 +655,7 @@ impl Routine { // parent_params.unwrap(). if routine_attr.contains(&RoutineAttr::RunOnce) { - return Ok(Routine { + return Ok(Arc::new(RwLock::new(Routine { name , module , channel , @@ -661,7 +666,7 @@ impl Routine { complete_iterations : 0 , remaining_iterations : None , routine_attr : routine_attr - }) ; + }))) ; } @@ -679,57 +684,80 @@ impl Routine { Err("NOT IMPLEMENTED".to_string()) } - pub async fn start(self) -> Result<String,String> + // pub async fn start(self) -> Result<String,String> + // pub async fn start(self : &mut Self) -> Result<String,String> + pub async fn start( + trg_routine_ar : Arc<RwLock<Routine>> + ) -> Result<String,String> { // [ ] Asyncio Spawn likely around here // [ ] & Assigns self.join_handle + // let self_rw = Arc::new(RwLock::new(self)); + // let mut self_wr_lock = self_rw.write().await; + // let self_ar = Arc::new(RwLock::new(trg_routine_ar)); - let self_rw = Arc::new(RwLock::new(self)); - let mut self_wr_lock = self_rw.write().await; - if self_wr_lock.routine_attr.contains(&RoutineAttr::RunOnce) { - self_wr_lock.remaining_iterations = Some(1); + if trg_routine_ar.read().await.routine_attr.contains(&RoutineAttr::RunOnce) { + // if self_wr_lock.routine_attr.contains(&RoutineAttr::RunOnce) { + // let = self_wr_lock.remaining_iterations + + // let mut self_wr_lock = self_rw.write().await; + + + // let self_rw_copy = Arc::new(self); + // let self_rw_copy = Arc::clone(&self_rw); + // let mut a = *(*self_wr_lock); + // a.remaining_iterations = Some(1); + // (*self_wr_lock).remaining_iterations = Some(1); + // let routine = *self_rw_copy.read().await; + + // fn innerhelper(self_rw : Arc<RwLock<&Routine>>) -> Option<JoinHandle<()>> { + // fn innerhelper(self_rw : Arc<RwLock<&Routine>>) -> Option<JoinHandle<()>> { + // fn innerhelper(inroutine : &Routine) -> Option<JoinHandle<()>> { + // fn innerhelper(inroutine : Routine) -> Option<JoinHandle<()>> { + fn innerhelper(inroutine : Arc<RwLock<Routine>>) -> Option<JoinHandle<()>> { - fn innerhelper(self_rw : Arc<RwLock<Routine>>) -> Option<JoinHandle<()>> { Some( tokio::spawn(async move { - let mut self_wr_lock = self_rw.write().await; - let mut remainingiter = self_wr_lock.remaining_iterations.unwrap(); + // let mut self_wr_lock = self_rw.write().await; + // let mut remainingiter = self_wr_lock.remaining_iterations.unwrap(); + let mut remainingiter = inroutine.write().await.remaining_iterations.unwrap_or(0); botlog::trace( format!( "[TRACE][Routine Started] {} in {}", - self_wr_lock.name,self_wr_lock.channel.0 + inroutine.read().await.name, + inroutine.read().await.channel.0 ) .as_str(), Some(format!( "Routine > start() > (In Tokio Spawn) > {:?}", - self_wr_lock.module + inroutine.read().await.module )), - Some(&self_wr_lock.parent_params.msg), + Some(&inroutine.read().await.parent_params.msg), ); - self_wr_lock.start_time = Some(chrono::offset::Local::now()); + inroutine.write().await.start_time = Some(chrono::offset::Local::now()); // Loop iteration while remainingiter > 1 { // execution body - self_wr_lock.loopbody().await; + inroutine.read().await.loopbody().await; // end of loop iteration remainingiter -= 1; { - self_wr_lock.remaining_iterations = Some(remainingiter); - self_wr_lock.complete_iterations += 1; + inroutine.write().await.remaining_iterations = Some(remainingiter); + inroutine.write().await.complete_iterations += 1; } } @@ -737,14 +765,15 @@ impl Routine { botlog::trace( format!( "[TRACE][Routine Completed] {} in {}", - self_wr_lock.name,self_wr_lock.channel.0 + inroutine.read().await.name, + inroutine.read().await.channel.0 ) .as_str(), Some(format!( "Routine > start() > (In Tokio Spawn) > {:?}", - self_wr_lock.module + inroutine.read().await.module )), - Some(&self_wr_lock.parent_params.msg), + Some(&inroutine.read().await.parent_params.msg), ); @@ -752,7 +781,20 @@ impl Routine { })) } - self_wr_lock.join_handle = innerhelper(self_rw.clone()) ; + + // let self_rw = Arc::new(RwLock::new(self)); + // let mut self_wr_lock = self_rw.write().await; + + // self_wr_lock.join_handle = innerhelper(&routine) ; + + // let mut routine = self_rw_copy.write().await; + // (**routine).join_handle = innerhelper(*routine); + // routine.join_handle = innerhelper(*routine); + // let routine = *self_rw_copy.read().await; + // self_rw_copy.write().await.join_handle = innerhelper(&routine); + // let self_ref = Arc::clone(&trg_routine_ar); + trg_routine_ar.write().await.join_handle = innerhelper(trg_routine_ar.clone()); + return Ok("Successfully Started Routine".to_string()); } @@ -762,14 +804,17 @@ impl Routine { botlog::trace( format!( "[ERROR][Routine NOT IMPLEMENTED] {} in {}", - self_wr_lock.name,self_wr_lock.channel.0 + // self_wr_lock.name,self_wr_lock.channel.0 + trg_routine_ar.read().await.name, + trg_routine_ar.read().await.channel.0 ) .as_str(), Some(format!( "Routine > start() > (In Tokio Spawn) > {:?}", - self_wr_lock.module + // self_wr_lock.module + trg_routine_ar.read().await.module )), - Some(&self_wr_lock.parent_params.msg), + Some(&trg_routine_ar.read().await.parent_params.msg), ); Log::flush(); diff --git a/src/core/chat.rs b/src/core/chat.rs index d0b85e6..a83bd8c 100644 --- a/src/core/chat.rs +++ b/src/core/chat.rs @@ -101,7 +101,7 @@ impl Chat { Some(¶ms.msg), ); - let parent_module = params.get_parent_module().await; + let parent_module = params.get_module().await; let params_clone = params.clone(); let botclone = Arc::clone(¶ms_clone.bot); diff --git a/src/custom/experimental/experiment003.rs b/src/custom/experimental/experiment003.rs index 0bb98b9..1e25591 100644 --- a/src/custom/experimental/experiment003.rs +++ b/src/custom/experimental/experiment003.rs @@ -16,6 +16,7 @@ const OF_CMD_CHANNEL:Channel = Channel(String::new()); use casual_logger::Log; use rand::Rng; +use tokio::sync::RwLock; use std::sync::Arc; use crate::core::bot_actions::ExecBodyParams; @@ -71,13 +72,19 @@ async fn test3_body(params : ExecBodyParams) { // [x] Get the module from params - let parentmodule = params.get_parent_module().await; - let channel = params.get_routine_channel().await; + // let parentmodule = params.get_parent_module().await; + let module = params.get_module().await; + let channel = params.get_channel().await; let routine_attr = vec![ RoutineAttr::RunOnce ]; - let exec_body = actions_util::asyncbox(rtestbody); - let parent_params = params.clone(); + // let exec_body = actions_util::asyncbox(rtestbody); + let exec_body = actions_util::asyncbox(rtestbody); // <-- 03.27 - when below is uncommented, this is throwing an issue + + + // let parent_params = params.clone(); + // let params_clone = params.clone(); + async fn rtestbody(params : ExecBodyParams) { @@ -94,19 +101,64 @@ async fn test3_body(params : ExecBodyParams) { String::from("Inner Routine Loop Message"), params.clone() ).await; + + let logmsg_botact = match *params.curr_act.read().await { + BotAction::C(_) => "command", + BotAction::R(_) => "routine", + BotAction::L(_) => "listener", + } ; + + botlog::trace( + // format!("Params > Curr_act : {:?}", params.curr_act).as_str(), // BotAction doesn't imblement debug + format!("Params > Curr_act type : {:?}", logmsg_botact).as_str(), + Some("Experiments003 > test3 command body".to_string()), + Some(¶ms.msg), + ); + Log::flush(); } + botlog::debug( + format!("TEST3_BODY BEFORE FROM CALL : module - {:?} ; channel - {:?}", + module,channel + ).as_str(), + Some("experiment003 > test3_body".to_string()), + Some(¶ms.msg), + ); + + + let a = Routine::from( "Routine Test".to_string(), - parentmodule, + module, channel.unwrap(), routine_attr, exec_body, - parent_params + params.clone() ); + + if let Ok(newr) = a { - let rslt = newr.start().await; + + // [ ] before execute , be sure to adjust curr_act + + let mut params_mut = params.clone(); + // let newr_ar = Arc::new(RwLock::new(newr)); + let newr_ar = newr.clone(); + + params_mut.curr_act = Arc::new(RwLock::new( + BotAction::R(newr_ar.clone()) + )); + + // let a = newr_ar.read().await; + // let rslt = (&*a).start().await; + + // let mut newr_lock = newr_ar.write().await; + + // let rslt = newr_ar.write().await.start().await; + let rslt = Routine::start(newr_ar.clone()).await; + + // let rslt = newr_ar.read().await.start().await; botlog::debug( @@ -117,7 +169,8 @@ async fn test3_body(params : ExecBodyParams) { Some(¶ms.msg), ); - + Log::flush(); + let bot = Arc::clone(¶ms.bot); let botlock = bot.read().await; @@ -132,13 +185,18 @@ async fn test3_body(params : ExecBodyParams) { params.clone() ).await; + newr.clone().write().await.join_handle.take().expect("Issue with join handle").await.unwrap(); + + // newr.read().await.join_handle.unwrap().await.unwrap(); + + } - - Log::flush(); + + } From b08d91af5d2c67a54f1921aee5640523c09aad22 Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Wed, 27 Mar 2024 10:18:13 -0400 Subject: [PATCH 06/33] (cont) start runonce --- src/core/botmodules.rs | 260 ++++++++++++++++++++--- src/custom/experimental/experiment003.rs | 9 +- 2 files changed, 237 insertions(+), 32 deletions(-) diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index 34c6b02..0e6dfc2 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -688,7 +688,8 @@ impl Routine { // pub async fn start(self : &mut Self) -> Result<String,String> pub async fn start( trg_routine_ar : Arc<RwLock<Routine>> - ) -> Result<String,String> + // ) -> Result<String,String> +) -> Result<Arc<RwLock<Routine>>,String> { // [ ] Asyncio Spawn likely around here @@ -718,50 +719,228 @@ impl Routine { // fn innerhelper(self_rw : Arc<RwLock<&Routine>>) -> Option<JoinHandle<()>> { // fn innerhelper(inroutine : &Routine) -> Option<JoinHandle<()>> { // fn innerhelper(inroutine : Routine) -> Option<JoinHandle<()>> { - fn innerhelper(inroutine : Arc<RwLock<Routine>>) -> Option<JoinHandle<()>> { + // async fn innerhelper(inroutine : Arc<RwLock<Routine>>) -> Option<JoinHandle<()>> { + async fn runonce_innerhelper(inroutine : Arc<RwLock<Routine>>) -> JoinHandle<()> { - Some( - tokio::spawn(async move { + botlog::trace( + "innerhelper() started", + Some(format!( + "Routine > start() > (In Tokio Spawn)", + )), + Some(&inroutine.read().await.parent_params.msg), + ); + + Log::flush(); + + // Some( + // tokio::spawn(async move { + + // botlog::trace( + // ">> Within Spawn", + // Some(format!( + // "Routine > start() > (In Tokio Spawn)", + // )), + // Some(&inroutine.read().await.parent_params.msg), + // ); + + // Log::flush(); + + + + // // let mut self_wr_lock = self_rw.write().await; + // // let mut remainingiter = self_wr_lock.remaining_iterations.unwrap(); + // let mut remainingiter = inroutine.write().await.remaining_iterations.unwrap_or(0); + + + + // botlog::trace( + // format!( + // "[TRACE][Routine Started] {} in {}", + // inroutine.read().await.name, + // inroutine.read().await.channel.0 + // ) + // .as_str(), + // Some(format!( + // "Routine > start() > (In Tokio Spawn) > {:?}", + // inroutine.read().await.module + // )), + // Some(&inroutine.read().await.parent_params.msg), + // ); + + // Log::flush(); + + // inroutine.write().await.start_time = Some(chrono::offset::Local::now()); + + + // // Loop iteration + // while remainingiter > 1 { + + // // execution body + // inroutine.read().await.loopbody().await; + + // // end of loop iteration + // remainingiter -= 1; + // { + // inroutine.write().await.remaining_iterations = Some(remainingiter); + // inroutine.write().await.complete_iterations += 1; + // } + + // } + + // botlog::trace( + // format!( + // "[TRACE][Routine Completed] {} in {}", + // inroutine.read().await.name, + // inroutine.read().await.channel.0 + // ) + // .as_str(), + // Some(format!( + // "Routine > start() > (In Tokio Spawn) > {:?}", + // inroutine.read().await.module + // )), + // Some(&inroutine.read().await.parent_params.msg), + // ); + + + // Log::flush(); + // })) + + return tokio::spawn(async move { + + botlog::trace( + ">> Within Spawn", + Some(format!( + "Routine > start() > (In Tokio Spawn)", + )), + Some(&inroutine.read().await.parent_params.msg), + ); + + Log::flush(); + + + // botlog::trace( + // &format!( + // ">> Within Spawn - Reamining Iter Eval : {:?}" + // ,inroutine.read().await.remaining_iterations), + // Some(format!( + // "Routine > start() > (In Tokio Spawn)", + // )), + // Some(&inroutine.read().await.parent_params.msg), + // ); + + // Log::flush(); + + botlog::trace( + ">> Within Spawn >> After remaining iter eval", + Some(format!( + "Routine > start() > (In Tokio Spawn)", + )), + Some(&inroutine.read().await.parent_params.msg), + ); + + Log::flush(); + + + botlog::trace( + ">> Within Spawn >> After remaining iter eval 2 ", + Some(format!( + "Routine > start() > (In Tokio Spawn)", + )), + Some(&inroutine.read().await.parent_params.msg), + ); + + Log::flush(); + + + botlog::trace( + ">> Within Spawn >> After remaining iter eval 3 ", + Some(format!( + "Routine > start() > (In Tokio Spawn)", + )), + Some(&inroutine.read().await.parent_params.msg), + ); + + Log::flush(); // let mut self_wr_lock = self_rw.write().await; // let mut remainingiter = self_wr_lock.remaining_iterations.unwrap(); - let mut remainingiter = inroutine.write().await.remaining_iterations.unwrap_or(0); + // let mut remainingiter = inroutine.write().await.remaining_iterations.unwrap_or(0); + // let mut remainingiter = inroutine.read().await.remaining_iterations.unwrap_or(0); + // let mut remainingiter = inroutine.read().await.remaining_iterations.unwrap_or(0); + // async fn setremain(inroutine : Arc<RwLock<Routine>> , number : Option<i64>) { + // inroutine.write().await.remaining_iterations = number; + // } + // if inroutine.read().await.remaining_iterations.is_none() { + // // inroutine.write().await.remaining_iterations = Some(0); + // // setremain(inroutine.clone(),Some(0)).await; + // } - botlog::trace( - format!( - "[TRACE][Routine Started] {} in {}", - inroutine.read().await.name, - inroutine.read().await.channel.0 - ) - .as_str(), - Some(format!( - "Routine > start() > (In Tokio Spawn) > {:?}", - inroutine.read().await.module - )), - Some(&inroutine.read().await.parent_params.msg), - ); + // botlog::trace( + // format!( + // "[TRACE][Routine Started] {} in {}", + // inroutine.read().await.name, + // inroutine.read().await.channel.0 + // ) + // .as_str(), + // Some(format!( + // "Routine > start() > (In Tokio Spawn) > {:?}", + // inroutine.read().await.module + // )), + // Some(&inroutine.read().await.parent_params.msg), + // ); - inroutine.write().await.start_time = Some(chrono::offset::Local::now()); + // botlog::trace( + // format!( + // "[TRACE][Routine Started] {} in {}", + // inroutine.read().await.name, + // inroutine.read().await.channel.0 + // ) + // .as_str(), + // Some(format!( + // "Routine > start() > (In Tokio Spawn) > {:?}", + // inroutine.read().await.module + // )), + // Some(&inroutine.read().await.parent_params.msg), + // ); + + // Log::flush(); + + // inroutine.write().await.start_time = Some(chrono::offset::Local::now()); + // { + // inroutine.write().await.start_time = Some(chrono::offset::Local::now()); + // } // Loop iteration - while remainingiter > 1 { + // while remainingiter > 1 { + // while inroutine.read().await.remaining_iterations.unwrap_or(0) > 1 { // execution body inroutine.read().await.loopbody().await; // end of loop iteration - remainingiter -= 1; - { - inroutine.write().await.remaining_iterations = Some(remainingiter); - inroutine.write().await.complete_iterations += 1; - } + + // let remain_iter = inroutine.read().await.remaining_iterations.unwrap_or(0); + + // { + // // inroutine.write().await.remaining_iterations = Some(remain_iter - 1); + // setremain(inroutine.clone(),Some(remain_iter - 1)).await; + // } + // { + // inroutine.write().await.complete_iterations += 1; + // } + + // remainingiter -= 1; + // { + // inroutine.write().await.remaining_iterations = Some(remainingiter); + // inroutine.write().await.complete_iterations += 1; + // } - } - + // } + botlog::trace( format!( "[TRACE][Routine Completed] {} in {}", @@ -778,7 +957,10 @@ impl Routine { Log::flush(); - })) + }) + + + } @@ -793,9 +975,17 @@ impl Routine { // let routine = *self_rw_copy.read().await; // self_rw_copy.write().await.join_handle = innerhelper(&routine); // let self_ref = Arc::clone(&trg_routine_ar); - trg_routine_ar.write().await.join_handle = innerhelper(trg_routine_ar.clone()); + // trg_routine_ar.write().await.join_handle = innerhelper(trg_routine_ar.clone()).await; + { + trg_routine_ar.write().await.join_handle = Some(runonce_innerhelper(trg_routine_ar.clone()).await); + } - return Ok("Successfully Started Routine".to_string()); + // if let Some(a) = &trg_routine_ar.read().await.join_handle { + // (*a).await.unwrap(); + // }; + + // return Ok("Successfully Started Routine".to_string()); + return Ok(trg_routine_ar); } @@ -825,6 +1015,16 @@ impl Routine { async fn loopbody(&self) { + botlog::trace( + "loopbody() started", + Some(format!( + "Routine > start() > (During Tokio Spawn) > Execution body", + )), + None, + ); + + Log::flush(); + (self.exec_body)( self.parent_params.clone() ).await; diff --git a/src/custom/experimental/experiment003.rs b/src/custom/experimental/experiment003.rs index 1e25591..76862f6 100644 --- a/src/custom/experimental/experiment003.rs +++ b/src/custom/experimental/experiment003.rs @@ -160,10 +160,15 @@ async fn test3_body(params : ExecBodyParams) { // let rslt = newr_ar.read().await.start().await; + let rsltstr = match rslt { + Ok(_) => "successful".to_string(), + Err(a) => a, + }; + botlog::debug( format!("TEST3_BODY RESULT : {:?}", - rslt + rsltstr ).as_str(), Some("experiment003 > test3_body".to_string()), Some(¶ms.msg), @@ -181,7 +186,7 @@ async fn test3_body(params : ExecBodyParams) { .chat .say_in_reply_to( ¶ms.msg, - format!("Routine Result : {:?}",rslt), + format!("Routine Result : {:?}",rsltstr), params.clone() ).await; From 8da8460e4739bda0e51fffc8fdb2003bc993c61e Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Wed, 27 Mar 2024 14:51:56 -0400 Subject: [PATCH 07/33] proper join handling at custom --- src/core/botmodules.rs | 7 ++-- src/custom/experimental/experiment003.rs | 45 ++++++++++++++++-------- 2 files changed, 36 insertions(+), 16 deletions(-) diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index 0e6dfc2..49fca78 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -622,7 +622,10 @@ pub struct Routine { exec_body: bot_actions::actions_util::ExecBody, // parent_params : Option<ExecBodyParams> , parent_params : ExecBodyParams , - pub join_handle : Option<JoinHandle<()>> , + // pub join_handle : Option<JoinHandle<()>> , + // pub join_handle : Option<JoinHandle<()>> , + // pub join_handle : Option<Arc<RwLock<JoinHandle<()>>>> , + pub join_handle : Option<Arc<RwLock<JoinHandle<()>>>> , start_time : Option<DateTime<Local>> , complete_iterations : i64 , remaining_iterations : Option<i64> , @@ -977,7 +980,7 @@ impl Routine { // let self_ref = Arc::clone(&trg_routine_ar); // trg_routine_ar.write().await.join_handle = innerhelper(trg_routine_ar.clone()).await; { - trg_routine_ar.write().await.join_handle = Some(runonce_innerhelper(trg_routine_ar.clone()).await); + trg_routine_ar.write().await.join_handle = Some(Arc::new(RwLock::new(runonce_innerhelper(trg_routine_ar.clone()).await))); } // if let Some(a) = &trg_routine_ar.read().await.join_handle { diff --git a/src/custom/experimental/experiment003.rs b/src/custom/experimental/experiment003.rs index 76862f6..1d76930 100644 --- a/src/custom/experimental/experiment003.rs +++ b/src/custom/experimental/experiment003.rs @@ -17,6 +17,7 @@ const OF_CMD_CHANNEL:Channel = Channel(String::new()); use casual_logger::Log; use rand::Rng; use tokio::sync::RwLock; +use std::borrow::Borrow; use std::sync::Arc; use crate::core::bot_actions::ExecBodyParams; @@ -88,19 +89,19 @@ async fn test3_body(params : ExecBodyParams) { async fn rtestbody(params : ExecBodyParams) { - let bot = Arc::clone(¶ms.bot); + // let bot = Arc::clone(¶ms.bot); - let botlock = bot.read().await; + // let botlock = bot.read().await; - // uses chat.say_in_reply_to() for the bot controls for messages - botlock - .botmgrs - .chat - .say_in_reply_to( - ¶ms.msg.clone(), - String::from("Inner Routine Loop Message"), - params.clone() - ).await; + // // uses chat.say_in_reply_to() for the bot controls for messages + // botlock + // .botmgrs + // .chat + // .say_in_reply_to( + // ¶ms.msg.clone(), + // String::from("Inner Routine Loop Message"), + // params.clone() + // ).await; let logmsg_botact = match *params.curr_act.read().await { BotAction::C(_) => "command", @@ -115,10 +116,16 @@ async fn test3_body(params : ExecBodyParams) { Some(¶ms.msg), ); Log::flush(); + + for _ in 0..5 { + println!("tester"); + sleep(Duration::from_secs_f64(0.5)).await; + } } + botlog::debug( - format!("TEST3_BODY BEFORE FROM CALL : module - {:?} ; channel - {:?}", + format!("RTESTBODY : module - {:?} ; channel - {:?}", module,channel ).as_str(), Some("experiment003 > test3_body".to_string()), @@ -190,10 +197,20 @@ async fn test3_body(params : ExecBodyParams) { params.clone() ).await; - newr.clone().write().await.join_handle.take().expect("Issue with join handle").await.unwrap(); + // [x] Will not be handling JoinHandles here . If immediate abort() handling is required, below is an example that works + /* - // newr.read().await.join_handle.unwrap().await.unwrap(); + let a = newr.clone().read().await.join_handle.clone(); + match a { + Some(b) => { + b.read().await.borrow().abort(); // [x] <-- This aborts if wanting to abort immediately + //() + }, + None => (), + } + + */ } From 226da4362a465345ce1c41b145d9b188f1f19157 Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Wed, 27 Mar 2024 16:04:15 -0400 Subject: [PATCH 08/33] comments cleanup --- src/core/botmodules.rs | 287 ++++++----------------------------------- 1 file changed, 37 insertions(+), 250 deletions(-) diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index 49fca78..eb12cc1 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -76,7 +76,6 @@ pub async fn init(mgr: Arc<ModulesManager>) { // 2. Add the BotAction to ModulesManager botc1.add_core_to_modmgr(Arc::clone(&mgr)).await; - // async fn cmd_enable(bot: BotAR, msg: PrivmsgMessage) { async fn cmd_enable(params : ExecBodyParams) { /* There should be additional validation checks @@ -260,7 +259,6 @@ pub async fn init(mgr: Arc<ModulesManager>) { // 2. Add the BotAction to ModulesManager botc1.add_core_to_modmgr(Arc::clone(&mgr)).await; - // async fn cmd_disable(bot: BotAR, msg: PrivmsgMessage) { async fn cmd_disable(params : ExecBodyParams) { /* There should be additional validation checks @@ -469,7 +467,6 @@ pub enum StatusType { pub enum BotAction { C(BotCommand), L(Listener), - // R(Routine), R(Arc<RwLock<Routine>>), } @@ -617,14 +614,9 @@ pub enum RoutineAttr { pub struct Routine { pub name : String , pub module : BotModule , // from() can determine this if passed parents_params - // pub channel : Option<Channel> , // Routines generally run by Channel ; but can be left None pub channel : Channel , // Requiring some channel context exec_body: bot_actions::actions_util::ExecBody, - // parent_params : Option<ExecBodyParams> , parent_params : ExecBodyParams , - // pub join_handle : Option<JoinHandle<()>> , - // pub join_handle : Option<JoinHandle<()>> , - // pub join_handle : Option<Arc<RwLock<JoinHandle<()>>>> , pub join_handle : Option<Arc<RwLock<JoinHandle<()>>>> , start_time : Option<DateTime<Local>> , complete_iterations : i64 , @@ -642,10 +634,7 @@ impl Routine { channel : Channel, routine_attr : Vec<RoutineAttr> , exec_body : bot_actions::actions_util::ExecBody , - // parent_params : Option<ExecBodyParams> parent_params : ExecBodyParams - // ) -> Result<String,String> { - // ) -> Result<Routine,String> { ) -> Result< Arc<RwLock<Routine>>, String @@ -655,8 +644,6 @@ impl Routine { // to ensure those params don't conflict // conlicts would throw an error - // parent_params.unwrap(). - if routine_attr.contains(&RoutineAttr::RunOnce) { return Ok(Arc::new(RwLock::new(Routine { name , @@ -687,42 +674,26 @@ impl Routine { Err("NOT IMPLEMENTED".to_string()) } - // pub async fn start(self) -> Result<String,String> - // pub async fn start(self : &mut Self) -> Result<String,String> pub async fn start( trg_routine_ar : Arc<RwLock<Routine>> // ) -> Result<String,String> -) -> Result<Arc<RwLock<Routine>>,String> + ) -> Result<Arc<RwLock<Routine>>,String> { // [ ] Asyncio Spawn likely around here // [ ] & Assigns self.join_handle - // let self_rw = Arc::new(RwLock::new(self)); - // let mut self_wr_lock = self_rw.write().await; - // let self_ar = Arc::new(RwLock::new(trg_routine_ar)); + /* + GENERAL LOGIC + 1. Create a loop scenario based on routine_attr such as RunOnce + 2. Run the loop depending on how the Routine is setup + + */ if trg_routine_ar.read().await.routine_attr.contains(&RoutineAttr::RunOnce) { - // if self_wr_lock.routine_attr.contains(&RoutineAttr::RunOnce) { - // let = self_wr_lock.remaining_iterations - - // let mut self_wr_lock = self_rw.write().await; - - // let self_rw_copy = Arc::new(self); - // let self_rw_copy = Arc::clone(&self_rw); - // let mut a = *(*self_wr_lock); - // a.remaining_iterations = Some(1); - // (*self_wr_lock).remaining_iterations = Some(1); - // let routine = *self_rw_copy.read().await; - - // fn innerhelper(self_rw : Arc<RwLock<&Routine>>) -> Option<JoinHandle<()>> { - // fn innerhelper(self_rw : Arc<RwLock<&Routine>>) -> Option<JoinHandle<()>> { - // fn innerhelper(inroutine : &Routine) -> Option<JoinHandle<()>> { - // fn innerhelper(inroutine : Routine) -> Option<JoinHandle<()>> { - // async fn innerhelper(inroutine : Arc<RwLock<Routine>>) -> Option<JoinHandle<()>> { async fn runonce_innerhelper(inroutine : Arc<RwLock<Routine>>) -> JoinHandle<()> { botlog::trace( @@ -734,79 +705,6 @@ impl Routine { ); Log::flush(); - - // Some( - // tokio::spawn(async move { - - // botlog::trace( - // ">> Within Spawn", - // Some(format!( - // "Routine > start() > (In Tokio Spawn)", - // )), - // Some(&inroutine.read().await.parent_params.msg), - // ); - - // Log::flush(); - - - - // // let mut self_wr_lock = self_rw.write().await; - // // let mut remainingiter = self_wr_lock.remaining_iterations.unwrap(); - // let mut remainingiter = inroutine.write().await.remaining_iterations.unwrap_or(0); - - - - // botlog::trace( - // format!( - // "[TRACE][Routine Started] {} in {}", - // inroutine.read().await.name, - // inroutine.read().await.channel.0 - // ) - // .as_str(), - // Some(format!( - // "Routine > start() > (In Tokio Spawn) > {:?}", - // inroutine.read().await.module - // )), - // Some(&inroutine.read().await.parent_params.msg), - // ); - - // Log::flush(); - - // inroutine.write().await.start_time = Some(chrono::offset::Local::now()); - - - // // Loop iteration - // while remainingiter > 1 { - - // // execution body - // inroutine.read().await.loopbody().await; - - // // end of loop iteration - // remainingiter -= 1; - // { - // inroutine.write().await.remaining_iterations = Some(remainingiter); - // inroutine.write().await.complete_iterations += 1; - // } - - // } - - // botlog::trace( - // format!( - // "[TRACE][Routine Completed] {} in {}", - // inroutine.read().await.name, - // inroutine.read().await.channel.0 - // ) - // .as_str(), - // Some(format!( - // "Routine > start() > (In Tokio Spawn) > {:?}", - // inroutine.read().await.module - // )), - // Some(&inroutine.read().await.parent_params.msg), - // ); - - - // Log::flush(); - // })) return tokio::spawn(async move { @@ -819,131 +717,25 @@ impl Routine { ); Log::flush(); + { + let mut a = inroutine.write().await; + a.start_time = Some(chrono::offset::Local::now()); + a.complete_iterations += 1; + if let Some(i) = a.remaining_iterations{ + if i > 0 { + a.remaining_iterations = Some(i-1) + } else { + // do nothing for now + // [ ] If this was in a loop, please validate this + } + + } + } - // botlog::trace( - // &format!( - // ">> Within Spawn - Reamining Iter Eval : {:?}" - // ,inroutine.read().await.remaining_iterations), - // Some(format!( - // "Routine > start() > (In Tokio Spawn)", - // )), - // Some(&inroutine.read().await.parent_params.msg), - // ); + // execution body + inroutine.read().await.loopbody().await; - // Log::flush(); - - botlog::trace( - ">> Within Spawn >> After remaining iter eval", - Some(format!( - "Routine > start() > (In Tokio Spawn)", - )), - Some(&inroutine.read().await.parent_params.msg), - ); - - Log::flush(); - - - botlog::trace( - ">> Within Spawn >> After remaining iter eval 2 ", - Some(format!( - "Routine > start() > (In Tokio Spawn)", - )), - Some(&inroutine.read().await.parent_params.msg), - ); - - Log::flush(); - - - botlog::trace( - ">> Within Spawn >> After remaining iter eval 3 ", - Some(format!( - "Routine > start() > (In Tokio Spawn)", - )), - Some(&inroutine.read().await.parent_params.msg), - ); - - Log::flush(); - - - // let mut self_wr_lock = self_rw.write().await; - // let mut remainingiter = self_wr_lock.remaining_iterations.unwrap(); - // let mut remainingiter = inroutine.write().await.remaining_iterations.unwrap_or(0); - // let mut remainingiter = inroutine.read().await.remaining_iterations.unwrap_or(0); - // let mut remainingiter = inroutine.read().await.remaining_iterations.unwrap_or(0); - - // async fn setremain(inroutine : Arc<RwLock<Routine>> , number : Option<i64>) { - // inroutine.write().await.remaining_iterations = number; - // } - - // if inroutine.read().await.remaining_iterations.is_none() { - // // inroutine.write().await.remaining_iterations = Some(0); - // // setremain(inroutine.clone(),Some(0)).await; - // } - - // botlog::trace( - // format!( - // "[TRACE][Routine Started] {} in {}", - // inroutine.read().await.name, - // inroutine.read().await.channel.0 - // ) - // .as_str(), - // Some(format!( - // "Routine > start() > (In Tokio Spawn) > {:?}", - // inroutine.read().await.module - // )), - // Some(&inroutine.read().await.parent_params.msg), - // ); - - // botlog::trace( - // format!( - // "[TRACE][Routine Started] {} in {}", - // inroutine.read().await.name, - // inroutine.read().await.channel.0 - // ) - // .as_str(), - // Some(format!( - // "Routine > start() > (In Tokio Spawn) > {:?}", - // inroutine.read().await.module - // )), - // Some(&inroutine.read().await.parent_params.msg), - // ); - - // Log::flush(); - - // inroutine.write().await.start_time = Some(chrono::offset::Local::now()); - // { - // inroutine.write().await.start_time = Some(chrono::offset::Local::now()); - // } - - - // Loop iteration - // while remainingiter > 1 { - // while inroutine.read().await.remaining_iterations.unwrap_or(0) > 1 { - - // execution body - inroutine.read().await.loopbody().await; - - // end of loop iteration - - // let remain_iter = inroutine.read().await.remaining_iterations.unwrap_or(0); - - // { - // // inroutine.write().await.remaining_iterations = Some(remain_iter - 1); - // setremain(inroutine.clone(),Some(remain_iter - 1)).await; - // } - // { - // inroutine.write().await.complete_iterations += 1; - // } - - // remainingiter -= 1; - // { - // inroutine.write().await.remaining_iterations = Some(remainingiter); - // inroutine.write().await.complete_iterations += 1; - // } - - // } - botlog::trace( format!( "[TRACE][Routine Completed] {} in {}", @@ -958,6 +750,20 @@ impl Routine { Some(&inroutine.read().await.parent_params.msg), ); + botlog::trace( + format!( + "[TRACE][Routine Completed][Routine Header Test] {} in {} > Completed Iterations : {}", + inroutine.read().await.name, + inroutine.read().await.channel.0 , + inroutine.read().await.complete_iterations, + ) + .as_str(), + Some(format!( + "Routine > start() > (In Tokio Spawn) > {:?}", + inroutine.read().await.module + )), + Some(&inroutine.read().await.parent_params.msg), + ); Log::flush(); }) @@ -967,27 +773,10 @@ impl Routine { } - // let self_rw = Arc::new(RwLock::new(self)); - // let mut self_wr_lock = self_rw.write().await; - - // self_wr_lock.join_handle = innerhelper(&routine) ; - - // let mut routine = self_rw_copy.write().await; - // (**routine).join_handle = innerhelper(*routine); - // routine.join_handle = innerhelper(*routine); - // let routine = *self_rw_copy.read().await; - // self_rw_copy.write().await.join_handle = innerhelper(&routine); - // let self_ref = Arc::clone(&trg_routine_ar); - // trg_routine_ar.write().await.join_handle = innerhelper(trg_routine_ar.clone()).await; { trg_routine_ar.write().await.join_handle = Some(Arc::new(RwLock::new(runonce_innerhelper(trg_routine_ar.clone()).await))); } - // if let Some(a) = &trg_routine_ar.read().await.join_handle { - // (*a).await.unwrap(); - // }; - - // return Ok("Successfully Started Routine".to_string()); return Ok(trg_routine_ar); } @@ -997,14 +786,12 @@ impl Routine { botlog::trace( format!( "[ERROR][Routine NOT IMPLEMENTED] {} in {}", - // self_wr_lock.name,self_wr_lock.channel.0 trg_routine_ar.read().await.name, trg_routine_ar.read().await.channel.0 ) .as_str(), Some(format!( "Routine > start() > (In Tokio Spawn) > {:?}", - // self_wr_lock.module trg_routine_ar.read().await.module )), Some(&trg_routine_ar.read().await.parent_params.msg), From 669b2da8716fa5b7516466afbd881391cd1992f7 Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Wed, 27 Mar 2024 17:03:23 -0400 Subject: [PATCH 09/33] cleanup start impl --- src/core/bot_actions.rs | 3 +- src/core/botmodules.rs | 223 ++++++++++++++++++++++------------------ 2 files changed, 124 insertions(+), 102 deletions(-) diff --git a/src/core/bot_actions.rs b/src/core/bot_actions.rs index a88e5de..9ff41b5 100644 --- a/src/core/bot_actions.rs +++ b/src/core/bot_actions.rs @@ -5,11 +5,12 @@ use tokio::sync::RwLock; use crate::core::botinstance::BotInstance; -use super::{botinstance::Channel, botmodules::{BotAction, BotModule}, identity::ChatBadge}; +use super::{botinstance::Channel, botmodules::{BotAction, BotModule, Routine}, identity::ChatBadge}; pub type BotAR = Arc<RwLock<BotInstance>>; pub type ActAR = Arc<RwLock<BotAction>>; +pub type RoutineAR = Arc<RwLock<Routine>>; #[derive(Clone)] pub struct ExecBodyParams { diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index eb12cc1..68129e1 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -25,6 +25,8 @@ const OF_CMD_CHANNEL:Channel = Channel(String::new()); use core::panic; +use std::borrow::Borrow; +use std::borrow::BorrowMut; use std::collections::HashMap; use std::sync::Arc; @@ -51,6 +53,8 @@ use crate::core::bot_actions; use std::hash::{Hash, Hasher}; +use super::bot_actions::ActAR; +use super::bot_actions::RoutineAR; use super::identity::ChatBadge; @@ -617,7 +621,7 @@ pub struct Routine { pub channel : Channel , // Requiring some channel context exec_body: bot_actions::actions_util::ExecBody, parent_params : ExecBodyParams , - pub join_handle : Option<Arc<RwLock<JoinHandle<()>>>> , + pub join_handle : Option<Arc<RwLock<JoinHandle<RoutineAR>>>> , start_time : Option<DateTime<Local>> , complete_iterations : i64 , remaining_iterations : Option<i64> , @@ -685,121 +689,138 @@ impl Routine { /* - GENERAL LOGIC + UMBRELLA ROUTINE LOGIC 1. Create a loop scenario based on routine_attr such as RunOnce 2. Run the loop depending on how the Routine is setup + + START LOGIC : + 1. Ideally validate the routineattr that they're not a problem scenario (However, this should have been validated At Setup) + a. Extra helper validation function though would help in case the attributes were changes between setup + 2. Use these attributes only in Critical areas of the loop logic to determine changes in Loop logic + */ + + // Use the following to stop the function from going any further if not implemented + if !trg_routine_ar.read().await.routine_attr.contains(&RoutineAttr::RunOnce) { + + + botlog::trace( + format!( + "[ERROR][Routine Feature NOT IMPLEMENTED] {} in {}", + trg_routine_ar.read().await.name, + trg_routine_ar.read().await.channel.0 + ) + .as_str(), + Some(format!( + "Routine > start() > (In Tokio Spawn) > {:?}", + trg_routine_ar.read().await.module + )), + Some(&trg_routine_ar.read().await.parent_params.msg), + ); + + Log::flush(); + + return Err("NOT IMPLEMENTED".to_string()) + + } - if trg_routine_ar.read().await.routine_attr.contains(&RoutineAttr::RunOnce) { - - async fn runonce_innerhelper(inroutine : Arc<RwLock<Routine>>) -> JoinHandle<()> { - - botlog::trace( - "innerhelper() started", - Some(format!( - "Routine > start() > (In Tokio Spawn)", - )), - Some(&inroutine.read().await.parent_params.msg), - ); - - Log::flush(); - - return tokio::spawn(async move { - - botlog::trace( - ">> Within Spawn", - Some(format!( - "Routine > start() > (In Tokio Spawn)", - )), - Some(&inroutine.read().await.parent_params.msg), - ); - - Log::flush(); - { - let mut a = inroutine.write().await; - a.start_time = Some(chrono::offset::Local::now()); - a.complete_iterations += 1; - if let Some(i) = a.remaining_iterations{ - - if i > 0 { - a.remaining_iterations = Some(i-1) - } else { - // do nothing for now - // [ ] If this was in a loop, please validate this - } - - } - } - - // execution body - inroutine.read().await.loopbody().await; - - botlog::trace( - format!( - "[TRACE][Routine Completed] {} in {}", - inroutine.read().await.name, - inroutine.read().await.channel.0 - ) - .as_str(), - Some(format!( - "Routine > start() > (In Tokio Spawn) > {:?}", - inroutine.read().await.module - )), - Some(&inroutine.read().await.parent_params.msg), - ); - - botlog::trace( - format!( - "[TRACE][Routine Completed][Routine Header Test] {} in {} > Completed Iterations : {}", - inroutine.read().await.name, - inroutine.read().await.channel.0 , - inroutine.read().await.complete_iterations, - ) - .as_str(), - Some(format!( - "Routine > start() > (In Tokio Spawn) > {:?}", - inroutine.read().await.module - )), - Some(&inroutine.read().await.parent_params.msg), - ); - - Log::flush(); - }) - - - - } - - - { - trg_routine_ar.write().await.join_handle = Some(Arc::new(RwLock::new(runonce_innerhelper(trg_routine_ar.clone()).await))); - } - - return Ok(trg_routine_ar); - - } - + let trg_routine_arout = Arc::clone(&trg_routine_ar); + botlog::trace( - format!( - "[ERROR][Routine NOT IMPLEMENTED] {} in {}", - trg_routine_ar.read().await.name, - trg_routine_ar.read().await.channel.0 - ) - .as_str(), - Some(format!( - "Routine > start() > (In Tokio Spawn) > {:?}", - trg_routine_ar.read().await.module + "innerhelper() started", + Some(format!( + "Routine > start() > (In Tokio Spawn)", )), Some(&trg_routine_ar.read().await.parent_params.msg), ); Log::flush(); - Err("NOT IMPLEMENTED".to_string()) + // Spawn the task + let join_handle = tokio::spawn(async move { + + botlog::trace( + ">> Within Spawn", + Some(format!( + "Routine > start() > (In Tokio Spawn)", + )), + Some(&trg_routine_ar.read().await.parent_params.msg), + ); + + Log::flush(); + { // Prior to Loop that calls Custom Routine Execution Body + let mut a = trg_routine_ar.write().await; + a.start_time = Some(chrono::offset::Local::now()); + } + + loop { // Routine loop + + + // execution body + trg_routine_ar.read().await.loopbody().await; + + + { // End of Loop iteration + let mut a = trg_routine_ar.write().await; + a.complete_iterations += 1; + if let Some(i) = a.remaining_iterations { + if i > 0 { a.remaining_iterations = Some(i-1) ; } + } + } + + // End of Loop Validation + + if trg_routine_ar.read().await.routine_attr.contains(&RoutineAttr::RunOnce) { + if trg_routine_ar.read().await.complete_iterations > 0 { break; } + } + + } + + + botlog::trace( + format!( + "[TRACE][Routine Completed] {} in {}", + trg_routine_ar.read().await.name, + trg_routine_ar.read().await.channel.0 + ) + .as_str(), + Some(format!( + "Routine > start() > (In Tokio Spawn) > {:?}", + trg_routine_ar.read().await.module + )), + Some(&trg_routine_ar.read().await.parent_params.msg), + ); + + botlog::trace( + format!( + "[TRACE][Routine Completed][Routine Header Test] {} in {} > Completed Iterations : {}", + trg_routine_ar.read().await.name, + trg_routine_ar.read().await.channel.0 , + trg_routine_ar.read().await.complete_iterations, + ) + .as_str(), + Some(format!( + "Routine > start() > (In Tokio Spawn) > {:?}", + trg_routine_ar.read().await.module + )), + Some(&trg_routine_ar.read().await.parent_params.msg), + ); + + Log::flush(); + trg_routine_ar + }); + + trg_routine_arout.write().await.join_handle = Some(Arc::new(RwLock::new(join_handle))); + + // } + + + return Ok(trg_routine_arout); + } From 537c3565a2a3440bbc6878a8011dfdc375d4b77e Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Wed, 27 Mar 2024 17:28:47 -0400 Subject: [PATCH 10/33] custom start test fn --- src/core/botmodules.rs | 4 +-- src/custom/experimental/experiment003.rs | 45 ++++++++++++------------ 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index 68129e1..c113af5 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -620,10 +620,10 @@ pub struct Routine { pub module : BotModule , // from() can determine this if passed parents_params pub channel : Channel , // Requiring some channel context exec_body: bot_actions::actions_util::ExecBody, - parent_params : ExecBodyParams , + pub parent_params : ExecBodyParams , pub join_handle : Option<Arc<RwLock<JoinHandle<RoutineAR>>>> , start_time : Option<DateTime<Local>> , - complete_iterations : i64 , + pub complete_iterations : i64 , remaining_iterations : Option<i64> , routine_attr : Vec<RoutineAttr> , } diff --git a/src/custom/experimental/experiment003.rs b/src/custom/experimental/experiment003.rs index 1d76930..5537d33 100644 --- a/src/custom/experimental/experiment003.rs +++ b/src/custom/experimental/experiment003.rs @@ -89,19 +89,6 @@ async fn test3_body(params : ExecBodyParams) { async fn rtestbody(params : ExecBodyParams) { - // let bot = Arc::clone(¶ms.bot); - - // let botlock = bot.read().await; - - // // uses chat.say_in_reply_to() for the bot controls for messages - // botlock - // .botmgrs - // .chat - // .say_in_reply_to( - // ¶ms.msg.clone(), - // String::from("Inner Routine Loop Message"), - // params.clone() - // ).await; let logmsg_botact = match *params.curr_act.read().await { BotAction::C(_) => "command", @@ -110,20 +97,27 @@ async fn test3_body(params : ExecBodyParams) { } ; botlog::trace( - // format!("Params > Curr_act : {:?}", params.curr_act).as_str(), // BotAction doesn't imblement debug format!("Params > Curr_act type : {:?}", logmsg_botact).as_str(), Some("Experiments003 > test3 command body".to_string()), Some(¶ms.msg), ); Log::flush(); - for _ in 0..5 { - println!("tester"); - sleep(Duration::from_secs_f64(0.5)).await; + if let BotAction::R(arr) = &*params.curr_act.read().await { + for curriter in 0..5 { + println!("tester - Routine - Completed Iterations : {}", + arr.read().await.complete_iterations); + println!("tester - Custom Loop - Completed Iterations : {}", + curriter); + sleep(Duration::from_secs_f64(0.5)).await; + } } + } + + botlog::debug( format!("RTESTBODY : module - {:?} ; channel - {:?}", module,channel @@ -149,7 +143,8 @@ async fn test3_body(params : ExecBodyParams) { // [ ] before execute , be sure to adjust curr_act - let mut params_mut = params.clone(); + // let mut params_mut = params.clone(); + let mut params_mut = params; // let newr_ar = Arc::new(RwLock::new(newr)); let newr_ar = newr.clone(); @@ -163,6 +158,12 @@ async fn test3_body(params : ExecBodyParams) { // let mut newr_lock = newr_ar.write().await; // let rslt = newr_ar.write().await.start().await; + + + { + newr_ar.write().await.parent_params = params_mut.clone(); + } + let rslt = Routine::start(newr_ar.clone()).await; // let rslt = newr_ar.read().await.start().await; @@ -178,12 +179,12 @@ async fn test3_body(params : ExecBodyParams) { rsltstr ).as_str(), Some("experiment003 > test3_body".to_string()), - Some(¶ms.msg), + Some(¶ms_mut.msg), ); Log::flush(); - let bot = Arc::clone(¶ms.bot); + let bot = Arc::clone(¶ms_mut.bot); let botlock = bot.read().await; @@ -192,9 +193,9 @@ async fn test3_body(params : ExecBodyParams) { .botmgrs .chat .say_in_reply_to( - ¶ms.msg, + ¶ms_mut.msg, format!("Routine Result : {:?}",rsltstr), - params.clone() + params_mut.clone() ).await; // [x] Will not be handling JoinHandles here . If immediate abort() handling is required, below is an example that works From 60fae25419294d9651b297072ba3928938d4e3a7 Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Wed, 27 Mar 2024 18:29:14 -0400 Subject: [PATCH 11/33] comments --- src/core/botmodules.rs | 170 +++++++++++++++++++++++++++++++---------- 1 file changed, 130 insertions(+), 40 deletions(-) diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index c113af5..f1997ad 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -631,8 +631,91 @@ pub struct Routine { impl Routine { + + + pub async fn validate_attr(routine_attr : &Vec<RoutineAttr>) + -> Result<String,String> + // [ ] => 03.27 - WIP + { + + /* + + GENERAL LOGIC : + [ ] 1. Define RoutineAttr in a broad level that are known to be implented or are work in progress + [ ] 2. Built in Logic will check these vectors, and return if Not Implemented + [ ] 3. If Implemented , then there are additional internal validation based on combination done later + + */ + + + // [x] 1. Define RoutineAttr in a broad level that are known to be implented or are work in progress + + // adjust the below for those that are work in progress or that are implemented + // - This will allow other functions to validate that it is implemented + + // WORK IN PROGRESS VECTOR - Vec<$RoutineAttr> + + let wip_attr:Vec<&RoutineAttr> = vec![ + &RoutineAttr::RunOnce + ]; + + let implemented_attr:Vec<&RoutineAttr> = vec![ + ]; + + + // [x] 2. Built in Logic will check these vectors, and return if Not Implemented + + let mut unimplemented = routine_attr.iter().filter(|x| !wip_attr.contains(x) && !implemented_attr.contains(x)); + + if unimplemented.next().is_some() { + + botlog::trace( + "[ERROR][Routine Feature NOT IMPLEMENTED]", + Some("Routine > Validate_attr()".to_string()), + None, + ); + + Log::flush(); + + return Err("NOT IMPLEMENTED".to_string()); + } + + + + + + // [ ] 3. If Implemented , then there are additional internal validation based on combination done later + + if routine_attr.contains(&RoutineAttr::RunOnce) { + return Ok("Valid & Implemented Setup".to_string()) + } + + + + + + + botlog::trace( + "[ERROR][Routine Feature NOT IMPLEMENTED]", + Some("Routine > Validate_attr()".to_string()), + None, + ); + + Log::flush(); + + return Err("NOT IMPLEMENTED".to_string()) + + } + + pub async fn validate_self_attr(self) + -> Result<String,String> + // [x] => 03.27 - COMPLETED + { + Routine::validate_attr(&self.routine_attr).await + } + // Constructor - pub fn from( + pub async fn from( name : String , module : BotModule , channel : Channel, @@ -642,35 +725,34 @@ impl Routine { ) -> Result< Arc<RwLock<Routine>>, String - > { + > + // [x] => 03.27 - COMPLETED + { - // [ ] Validation is made against parent_params - // to ensure those params don't conflict - // conlicts would throw an error - - if routine_attr.contains(&RoutineAttr::RunOnce) { - return Ok(Arc::new(RwLock::new(Routine { - name , - module , - channel , - exec_body , - parent_params , - join_handle : None , - start_time : None , - complete_iterations : 0 , - remaining_iterations : None , - routine_attr : routine_attr - }))) ; - } + Routine::validate_attr(&routine_attr).await?; + + return Ok(Arc::new(RwLock::new(Routine { + name , + module , + channel , + exec_body , + parent_params , + join_handle : None , + start_time : None , + complete_iterations : 0 , + remaining_iterations : None , + routine_attr : routine_attr + }))) ; - Err("NOT IMPLEMENTED".to_string()) } pub fn change_channel( &self, _channel : Channel - ) -> Result<String,String> { + ) -> Result<String,String> + // [ ] => 03.27 - WIP - NOT IMPLEMENTED + { // [ ] Think Ideally it should try to // change the target channel of the // internal process too if possible? @@ -682,6 +764,7 @@ impl Routine { trg_routine_ar : Arc<RwLock<Routine>> // ) -> Result<String,String> ) -> Result<Arc<RwLock<Routine>>,String> + // [ ] => 03.27 - WIP { // [ ] Asyncio Spawn likely around here @@ -703,28 +786,30 @@ impl Routine { // Use the following to stop the function from going any further if not implemented - if !trg_routine_ar.read().await.routine_attr.contains(&RoutineAttr::RunOnce) { + + Routine::validate_attr(&trg_routine_ar.read().await.routine_attr).await?; + // if !trg_routine_ar.read().await.routine_attr.contains(&RoutineAttr::RunOnce) { - botlog::trace( - format!( - "[ERROR][Routine Feature NOT IMPLEMENTED] {} in {}", - trg_routine_ar.read().await.name, - trg_routine_ar.read().await.channel.0 - ) - .as_str(), - Some(format!( - "Routine > start() > (In Tokio Spawn) > {:?}", - trg_routine_ar.read().await.module - )), - Some(&trg_routine_ar.read().await.parent_params.msg), - ); + // botlog::trace( + // format!( + // "[ERROR][Routine Feature NOT IMPLEMENTED] {} in {}", + // trg_routine_ar.read().await.name, + // trg_routine_ar.read().await.channel.0 + // ) + // .as_str(), + // Some(format!( + // "Routine > start() > (In Tokio Spawn) > {:?}", + // trg_routine_ar.read().await.module + // )), + // Some(&trg_routine_ar.read().await.parent_params.msg), + // ); - Log::flush(); + // Log::flush(); - return Err("NOT IMPLEMENTED".to_string()) + // return Err("NOT IMPLEMENTED".to_string()) - } + // } let trg_routine_arout = Arc::clone(&trg_routine_ar); @@ -773,6 +858,7 @@ impl Routine { } // End of Loop Validation + // These generally may include routine_attr related checks if trg_routine_ar.read().await.routine_attr.contains(&RoutineAttr::RunOnce) { if trg_routine_ar.read().await.complete_iterations > 0 { break; } @@ -824,7 +910,8 @@ impl Routine { } - async fn loopbody(&self) + async fn loopbody(&self) + // [x] => 03.27 - COMPLETED { botlog::trace( "loopbody() started", @@ -842,6 +929,7 @@ impl Routine { } pub async fn stop(&self) -> Result<String,String> + // [ ] => 03.27 - WIP - NOT IMPLEMENTED { @@ -871,6 +959,7 @@ impl Routine { &self, _force : bool ) -> Result<String,String> + // [ ] => 03.27 - WIP - NOT IMPLEMENTED { // force flag aborts the routine immediately (like cancel()) @@ -897,6 +986,7 @@ impl Routine { } pub async fn cancel(&self) -> Result<String,String> + // [ ] => 03.27 - WIP - NOT IMPLEMENTED { // [ ] Likely calls abort() From e963ae250df15c4b2d56f80ad1c323df97bce450 Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Wed, 27 Mar 2024 23:00:04 -0400 Subject: [PATCH 12/33] (cont) routine methods --- src/core/botmodules.rs | 130 +++++++++++++++++++++-- src/custom/experimental/experiment003.rs | 2 +- 2 files changed, 121 insertions(+), 11 deletions(-) diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index f1997ad..bbed7fb 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -35,6 +35,7 @@ use casual_logger::Log; use chrono::DateTime; // use chrono::Duration; use chrono::Local; +use chrono::OutOfRangeError; use tokio::sync::RwLock; use async_trait::async_trait; @@ -655,17 +656,25 @@ impl Routine { // WORK IN PROGRESS VECTOR - Vec<$RoutineAttr> - let wip_attr:Vec<&RoutineAttr> = vec![ - &RoutineAttr::RunOnce + let wip_attr:Vec<RoutineAttr> = vec![ + RoutineAttr::RunOnce, + RoutineAttr::ScheduledStart(chrono::offset::Local::now()), + RoutineAttr::DelayedStart, ]; - let implemented_attr:Vec<&RoutineAttr> = vec![ + let implemented_attr:Vec<RoutineAttr> = vec![ ]; // [x] 2. Built in Logic will check these vectors, and return if Not Implemented - let mut unimplemented = routine_attr.iter().filter(|x| !wip_attr.contains(x) && !implemented_attr.contains(x)); + let mut unimplemented = routine_attr.iter() + .filter(|x| { + let inx = x; + wip_attr.iter().filter(|y| matches!(y,i if i == inx)).next().is_none() + || implemented_attr.iter().filter(|y| matches!(y,i if i == inx)).next().is_none() + } + ); if unimplemented.next().is_some() { @@ -690,6 +699,23 @@ impl Routine { return Ok("Valid & Implemented Setup".to_string()) } + if routine_attr.contains(&RoutineAttr::RunOnce) & + routine_attr.contains(&RoutineAttr::LoopInfinitely) + { + return Err("Conflicting Routine Attributes".to_string()) + } + + + // [x] Err if DelayedStart but no LoopDuration + if routine_attr.contains(&RoutineAttr::DelayedStart) && + routine_attr.iter() + .filter(|x| matches!(x,&&RoutineAttr::LoopDuration(_)) ) + .next().is_none() + { + return Err("DelayedStart must include a LoopDuration".to_string()) + } + + @@ -837,19 +863,103 @@ impl Routine { ); Log::flush(); - { // Prior to Loop that calls Custom Routine Execution Body + + // [ ] If Scheduled Start or Delayed Start, Handle that first + + + fn duration_to_datetime(future_dt: DateTime<Local>) -> Result<Duration,OutOfRangeError> + { + (future_dt - chrono::offset::Local::now()).to_std() + } + + let delayduration = { + + let lock = trg_routine_ar.read().await; + + let mut related_attrs = lock + .routine_attr.iter() + .filter(|x| matches!(x,&&RoutineAttr::DelayedStart) || matches!(x,&&RoutineAttr::ScheduledStart(_)) ); + + // match related_attrs.next() { + + // } + + async fn duration_from_attr(attr: &RoutineAttr,trg_routine_ar : RoutineAR) -> Option<Duration> { + // let duration_from_attr = async { + let lock = trg_routine_ar.read().await; + + match attr { + RoutineAttr::ScheduledStart(dt) => { + if let Ok(dur) = duration_to_datetime(*dt) { + Some(dur) + } else { None } + }, + RoutineAttr::DelayedStart => { + let mut loopdur_attr_iter = lock + .routine_attr.iter() + .filter(|x| matches!(x,&&RoutineAttr::LoopDuration(_)) ); + + if let Some(loopdur_attr) = loopdur_attr_iter.next() { + if let RoutineAttr::LoopDuration(dur) = loopdur_attr { + Some(*dur) + } else { None } + } else { None } + // None + }, + _ => { None } // Handle no other combination + } + } + + // The following is done twice just in case ScheduledStart and DelayedStart are defined + let delayduration01 = if let Some(attr) = related_attrs.next() { + duration_from_attr(attr, trg_routine_ar.clone()).await + } else { None }; + + let delayduration02 = if let Some(attr) = related_attrs.next() { + duration_from_attr(attr, trg_routine_ar.clone()).await + } else { None }; + + // if there is a 2nd related duration, pick the minimum, otherwise, pick the results of delayduration01 + if delayduration02.is_some() { + Some(Duration::min(delayduration01.unwrap(),delayduration02.unwrap())) + } else { delayduration01 } + + }; + + + botlog::trace( + format!( + "[TRACE][Routine Processing] {} in {} > Delay Duration - {:?} ", + trg_routine_ar.read().await.name, + trg_routine_ar.read().await.channel.0 , + delayduration , + ) + .as_str(), + Some(format!( + "Routine > start() > (In Tokio Spawn) > {:?}", + trg_routine_ar.read().await.module + )), + Some(&trg_routine_ar.read().await.parent_params.msg), + ); + + if let Some(dur) = delayduration { + sleep(dur).await; + } + + + { // [x] Prior to Loop that calls Custom Routine Execution Body let mut a = trg_routine_ar.write().await; a.start_time = Some(chrono::offset::Local::now()); } - loop { // Routine loop + loop { // [x] Routine loop - // execution body + // [x] execution body trg_routine_ar.read().await.loopbody().await; - { // End of Loop iteration + { // [x] End of Loop iteration let mut a = trg_routine_ar.write().await; a.complete_iterations += 1; if let Some(i) = a.remaining_iterations { @@ -857,8 +967,8 @@ impl Routine { } } - // End of Loop Validation - // These generally may include routine_attr related checks + // [x]End of Loop Validation + // These generally may include routine_attr related checks to , for example, break out of the loop if trg_routine_ar.read().await.routine_attr.contains(&RoutineAttr::RunOnce) { if trg_routine_ar.read().await.complete_iterations > 0 { break; } diff --git a/src/custom/experimental/experiment003.rs b/src/custom/experimental/experiment003.rs index 5537d33..9b8f91e 100644 --- a/src/custom/experimental/experiment003.rs +++ b/src/custom/experimental/experiment003.rs @@ -135,7 +135,7 @@ async fn test3_body(params : ExecBodyParams) { routine_attr, exec_body, params.clone() - ); + ).await; From 6c3a151668ae24b06e72686770667dae627f8700 Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Wed, 27 Mar 2024 23:56:34 -0400 Subject: [PATCH 13/33] impl other routine attr --- src/core/botmodules.rs | 120 ++++++++++++++++++++++++++++++++--------- 1 file changed, 94 insertions(+), 26 deletions(-) diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index bbed7fb..b5544cf 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -636,15 +636,15 @@ impl Routine { pub async fn validate_attr(routine_attr : &Vec<RoutineAttr>) -> Result<String,String> - // [ ] => 03.27 - WIP + // [ ] => 03.27 - REVIEW FOR COMPLETION { /* GENERAL LOGIC : - [ ] 1. Define RoutineAttr in a broad level that are known to be implented or are work in progress - [ ] 2. Built in Logic will check these vectors, and return if Not Implemented - [ ] 3. If Implemented , then there are additional internal validation based on combination done later + [x] 1. Define RoutineAttr in a broad level that are known to be implented or are work in progress + [x] 2. Built in Logic will check these vectors, and return if Not Implemented + [x] 3. If Implemented , then there are additional internal validation based on combination done later */ @@ -657,9 +657,14 @@ impl Routine { // WORK IN PROGRESS VECTOR - Vec<$RoutineAttr> let wip_attr:Vec<RoutineAttr> = vec![ - RoutineAttr::RunOnce, - RoutineAttr::ScheduledStart(chrono::offset::Local::now()), RoutineAttr::DelayedStart, + RoutineAttr::ScheduledStart(chrono::offset::Local::now()), + RoutineAttr::LoopDuration(Duration::from_secs(1)), + RoutineAttr::LoopInfinitely, // Note : There's no added implementation for this + RoutineAttr::RunOnce, + RoutineAttr::MaxTimeThreshold(chrono::offset::Local::now()), + RoutineAttr::MaxIterations(1), + ]; let implemented_attr:Vec<RoutineAttr> = vec![ @@ -693,18 +698,27 @@ impl Routine { - // [ ] 3. If Implemented , then there are additional internal validation based on combination done later + // [x] 3. If Implemented , then there are additional internal validation based on combination done later to ERR - if routine_attr.contains(&RoutineAttr::RunOnce) { - return Ok("Valid & Implemented Setup".to_string()) - } - - if routine_attr.contains(&RoutineAttr::RunOnce) & - routine_attr.contains(&RoutineAttr::LoopInfinitely) + // Below ensures a routine_attr containing LoopInfinitely does not contain conflicit attributes + if routine_attr.contains(&RoutineAttr::LoopInfinitely) && + ( routine_attr.contains(&RoutineAttr::RunOnce) + || routine_attr.iter().filter(|y| matches!(y,&&RoutineAttr::MaxIterations(_))).next().is_some() + || routine_attr.iter().filter(|y| matches!(y,&&RoutineAttr::MaxTimeThreshold(_))).next().is_some() + ) { return Err("Conflicting Routine Attributes".to_string()) } + // [x] if there is no RunOnce, there must be a LoopDuration + if !routine_attr.contains(&RoutineAttr::RunOnce) + && routine_attr.iter() + .filter(|x| matches!(x,&&RoutineAttr::LoopDuration(_)) ) + .next().is_none() + { + return Err("LoopDuration is required if not RunOnce".to_string()); + } + // [x] Err if DelayedStart but no LoopDuration if routine_attr.contains(&RoutineAttr::DelayedStart) && @@ -718,18 +732,44 @@ impl Routine { + // [x] 4. If all other failure checks above works, ensure one more time that the attribute is implemented + // - If not, routine NOT IMPLEMENTED error + if routine_attr.iter() + .filter(|x| { + let inx = x; + wip_attr.iter().filter(|y| matches!(y,i if i == inx)).next().is_none() + || implemented_attr.iter().filter(|y| matches!(y,i if i == inx)).next().is_none() + }) + .next() + .is_none() + { + + botlog::trace( + "[ERROR][Routine Feature NOT IMPLEMENTED]", + Some("Routine > Validate_attr()".to_string()), + None, + ); + Log::flush(); - botlog::trace( - "[ERROR][Routine Feature NOT IMPLEMENTED]", - Some("Routine > Validate_attr()".to_string()), - None, - ); + Ok("Implemented & Validated".to_string()) - Log::flush(); + } else { + + + botlog::trace( + "[ERROR][Routine Feature NOT IMPLEMENTED]", + Some("Routine > Validate_attr()".to_string()), + None, + ); + + Log::flush(); + + Err("NOT IMPLEMENTED".to_string()) + + } - return Err("NOT IMPLEMENTED".to_string()) } @@ -790,11 +830,11 @@ impl Routine { trg_routine_ar : Arc<RwLock<Routine>> // ) -> Result<String,String> ) -> Result<Arc<RwLock<Routine>>,String> - // [ ] => 03.27 - WIP + // [ ] => 03.27 - REVIEW FOR COMPLETION { - // [ ] Asyncio Spawn likely around here - // [ ] & Assigns self.join_handle + // [x] Asyncio Spawn likely around here + // [x] & Assigns self.join_handle /* @@ -864,16 +904,19 @@ impl Routine { Log::flush(); - // [ ] If Scheduled Start or Delayed Start, Handle that first + // [x] If Scheduled Start or Delayed Start, Handle that first fn duration_to_datetime(future_dt: DateTime<Local>) -> Result<Duration,OutOfRangeError> { (future_dt - chrono::offset::Local::now()).to_std() } + + let delayduration = { + let lock = trg_routine_ar.read().await; let mut related_attrs = lock @@ -947,9 +990,17 @@ impl Routine { } - { // [x] Prior to Loop that calls Custom Routine Execution Body + { // [x] Loop Initialization - Prior to Loop that calls Custom Routine Execution Body let mut a = trg_routine_ar.write().await; a.start_time = Some(chrono::offset::Local::now()); + + if let Some(&RoutineAttr::MaxIterations(iternum)) = + a.routine_attr.iter() + .filter(|x| matches!(x,RoutineAttr::MaxIterations(_))) + .next() + { + a.remaining_iterations = Some(iternum); + } } loop { // [x] Routine loop @@ -964,16 +1015,33 @@ impl Routine { a.complete_iterations += 1; if let Some(i) = a.remaining_iterations { if i > 0 { a.remaining_iterations = Some(i-1) ; } + else { break ; } // if remaining iterations is 0, exit } } - // [x]End of Loop Validation + // [x] End of Loop Validation // These generally may include routine_attr related checks to , for example, break out of the loop if trg_routine_ar.read().await.routine_attr.contains(&RoutineAttr::RunOnce) { if trg_routine_ar.read().await.complete_iterations > 0 { break; } } + // return if max time has passed + if let Some(&RoutineAttr::MaxTimeThreshold(dt)) = trg_routine_ar.read().await.routine_attr.iter() + .filter(|x| matches!(x,&&RoutineAttr::MaxTimeThreshold(_)) ) + .next() { + if chrono::offset::Local::now() > dt { break; } + } + + // [x] Checks for Loop duration to sleep + if let Some(&RoutineAttr::LoopDuration(dur)) = trg_routine_ar.read().await.routine_attr.iter() + .filter(|x| matches!(x,&&RoutineAttr::LoopDuration(_)) ) + .next() + { + sleep(dur).await; + }; + + } From 4637312da941defa8fd0bd94cfedee158250ec7f Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Thu, 28 Mar 2024 02:13:38 -0400 Subject: [PATCH 14/33] impl stop --- src/core/botmodules.rs | 144 +++++++++++++++++++++++++++-------------- 1 file changed, 95 insertions(+), 49 deletions(-) diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index b5544cf..08225a9 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -615,6 +615,14 @@ pub enum RoutineAttr { */ +// For some key statuses and in particular Stopping to Gracefully stop +pub enum RoutineSignal { + Stopping, // Gracefully Stopping + Stopped, // When cancelling or aborting, this also is represented by Stopped + Started, // After Routine Started + NotStarted, +} + // #[derive(Debug)] pub struct Routine { pub name : String , @@ -627,6 +635,7 @@ pub struct Routine { pub complete_iterations : i64 , remaining_iterations : Option<i64> , routine_attr : Vec<RoutineAttr> , + pub internal_signal : RoutineSignal , } @@ -807,25 +816,13 @@ impl Routine { start_time : None , complete_iterations : 0 , remaining_iterations : None , - routine_attr : routine_attr + routine_attr : routine_attr , + internal_signal : RoutineSignal::NotStarted , }))) ; } - pub fn change_channel( - &self, - _channel : Channel - ) -> Result<String,String> - // [ ] => 03.27 - WIP - NOT IMPLEMENTED - { - // [ ] Think Ideally it should try to - // change the target channel of the - // internal process too if possible? - - Err("NOT IMPLEMENTED".to_string()) - } - pub async fn start( trg_routine_ar : Arc<RwLock<Routine>> // ) -> Result<String,String> @@ -1012,11 +1009,20 @@ impl Routine { { // [x] End of Loop iteration let mut a = trg_routine_ar.write().await; + + // [x] Check if Gracefully Stopping Signal was sent + if matches!(a.internal_signal,RoutineSignal::Stopping) { + a.internal_signal = RoutineSignal::Stopped; + break ; + } + + // [x] Check and adjust iterations a.complete_iterations += 1; if let Some(i) = a.remaining_iterations { if i > 0 { a.remaining_iterations = Some(i-1) ; } else { break ; } // if remaining iterations is 0, exit } + } // [x] End of Loop Validation @@ -1078,16 +1084,21 @@ impl Routine { trg_routine_ar }); - trg_routine_arout.write().await.join_handle = Some(Arc::new(RwLock::new(join_handle))); - // } + { // Recommendation to ensure a clean update is to use one write() lock that was awaited + // - We can isolate the write lock by ensuring it's in it's own block + let mut lock = trg_routine_arout.write().await; + lock.join_handle = Some(Arc::new(RwLock::new(join_handle))); + lock.internal_signal = RoutineSignal::Started; + + } + trg_routine_arout.write().await.internal_signal = RoutineSignal::Started; return Ok(trg_routine_arout); } - async fn loopbody(&self) // [x] => 03.27 - COMPLETED { @@ -1106,18 +1117,24 @@ impl Routine { ).await; } - pub async fn stop(&self) -> Result<String,String> - // [ ] => 03.27 - WIP - NOT IMPLEMENTED + pub async fn stop(&mut self) -> Result<String,String> + // [ ] => 03.27 - REVIEW FOR COMPLETION { let self_rw = Arc::new(RwLock::new(self)); + + { + let mut self_lock = self_rw.write().await; + self_lock.internal_signal = RoutineSignal::Stopping; + } + + let self_lock = self_rw.read().await; - botlog::trace( format!( - "[ERROR][Routine NOT IMPLEMENTED] {} in {}", + "[ROUTINE][Sent Gracefully Stopp Signal] {} in {}", self_lock.name,self_lock.channel.0 ) .as_str(), @@ -1130,37 +1147,24 @@ impl Routine { Log::flush(); - Err("NOT IMPLEMENTED".to_string()) - } + Ok("Sent Gracefully Stop Signal".to_string()) - pub async fn restart( - &self, - _force : bool - ) -> Result<String,String> - // [ ] => 03.27 - WIP - NOT IMPLEMENTED - { - // force flag aborts the routine immediately (like cancel()) + // botlog::trace( + // format!( + // "[ERROR][Routine NOT IMPLEMENTED] {} in {}", + // self_lock.name,self_lock.channel.0 + // ) + // .as_str(), + // Some(format!( + // "Routine > start() > (In Tokio Spawn) > {:?}", + // self_lock.module + // )), + // Some(&self_lock.parent_params.msg), + // ); - - let self_rw = Arc::new(RwLock::new(self)); - let self_lock = self_rw.read().await; - + // Log::flush(); - botlog::trace( - format!( - "[ERROR][Routine NOT IMPLEMENTED] {} in {}", - self_lock.name,self_lock.channel.0 - ) - .as_str(), - Some(format!( - "Routine > start() > (In Tokio Spawn) > {:?}", - self_lock.module - )), - Some(&self_lock.parent_params.msg), - ); - - Log::flush(); - Err("NOT IMPLEMENTED".to_string()) + // Err("NOT IMPLEMENTED".to_string()) } pub async fn cancel(&self) -> Result<String,String> @@ -1194,6 +1198,48 @@ impl Routine { Err("NOT IMPLEMENTED".to_string()) } + pub async fn restart( + &self, + _force : bool + ) -> Result<String,String> + // [ ] => 03.27 - WIP - NOT IMPLEMENTED + { + // force flag aborts the routine immediately (like cancel()) + + + let self_rw = Arc::new(RwLock::new(self)); + let self_lock = self_rw.read().await; + + + botlog::trace( + format!( + "[ERROR][Routine NOT IMPLEMENTED] {} in {}", + self_lock.name,self_lock.channel.0 + ) + .as_str(), + Some(format!( + "Routine > start() > (In Tokio Spawn) > {:?}", + self_lock.module + )), + Some(&self_lock.parent_params.msg), + ); + + Log::flush(); + Err("NOT IMPLEMENTED".to_string()) + } + + pub fn change_channel( + &self, + _channel : Channel + ) -> Result<String,String> + // [ ] => 03.27 - WIP - NOT IMPLEMENTED + { + // [ ] Think Ideally it should try to + // change the target channel of the + // internal process too if possible? + + Err("NOT IMPLEMENTED".to_string()) + } } From ca9361cc935ea73bd95743dc76dcd7a96187bdc6 Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Thu, 28 Mar 2024 03:18:41 -0400 Subject: [PATCH 15/33] routine methods --- src/core/botmodules.rs | 154 +++++++++++++++++++++++++++++++++++------ 1 file changed, 131 insertions(+), 23 deletions(-) diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index 08225a9..e320e7f 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -28,6 +28,7 @@ use core::panic; use std::borrow::Borrow; use std::borrow::BorrowMut; use std::collections::HashMap; +use std::ops::DerefMut; use std::sync::Arc; use casual_logger::Log; @@ -1134,12 +1135,12 @@ impl Routine { botlog::trace( format!( - "[ROUTINE][Sent Gracefully Stopp Signal] {} in {}", + "[ROUTINE][Sent Gracefully Stop Signal] {} in {}", self_lock.name,self_lock.channel.0 ) .as_str(), Some(format!( - "Routine > start() > (In Tokio Spawn) > {:?}", + "Routine > stop() > {:?}", self_lock.module )), Some(&self_lock.parent_params.msg), @@ -1167,78 +1168,185 @@ impl Routine { // Err("NOT IMPLEMENTED".to_string()) } - pub async fn cancel(&self) -> Result<String,String> - // [ ] => 03.27 - WIP - NOT IMPLEMENTED + pub async fn cancel(&mut self) -> Result<String,String> + // [ ] => 03.27 - REVIEW FOR COMPLETION { // [ ] Likely calls abort() // Related : // https://docs.rs/tokio/latest/tokio/task/struct.JoinHandle.html#method.abort - - + let self_rw = Arc::new(RwLock::new(self)); let self_lock = self_rw.read().await; - + + + match &self_lock.join_handle { + None => return Err("No Join Handle on the Routine to Cancel".to_string()), + Some(a) => { + a.read().await.abort(); + { + let mut lock_mut = self_rw.write().await; + lock_mut.internal_signal = RoutineSignal::Stopped; + + } + } + } + botlog::trace( format!( - "[ERROR][Routine NOT IMPLEMENTED] {} in {}", + "[ROUTINE][Cancelled Routine] {} in {}", self_lock.name,self_lock.channel.0 ) .as_str(), Some(format!( - "Routine > start() > (In Tokio Spawn) > {:?}", + "Routine > cancel() > {:?}", self_lock.module )), Some(&self_lock.parent_params.msg), ); Log::flush(); - Err("NOT IMPLEMENTED".to_string()) + Ok("Cancelled Successfully".to_string()) + + + // botlog::trace( + // format!( + // "[ERROR][Routine NOT IMPLEMENTED] {} in {}", + // self_lock.name,self_lock.channel.0 + // ) + // .as_str(), + // Some(format!( + // "Routine > start() > (In Tokio Spawn) > {:?}", + // self_lock.module + // )), + // Some(&self_lock.parent_params.msg), + // ); + + // Log::flush(); + // Err("NOT IMPLEMENTED".to_string()) } pub async fn restart( - &self, - _force : bool + // &mut self, + self, + force : bool ) -> Result<String,String> - // [ ] => 03.27 - WIP - NOT IMPLEMENTED + // [ ] => 03.27 - REVIEW FOR COMPLETION { // force flag aborts the routine immediately (like cancel()) let self_rw = Arc::new(RwLock::new(self)); - let self_lock = self_rw.read().await; + + if force + { + let mut self_lock = self_rw.write().await; + self_lock.cancel().await?; + } else { + let mut self_lock = self_rw.write().await; + self_lock.stop().await?; + } + + Routine::start(self_rw.clone()).await?; + let self_lock = self_rw.read().await; botlog::trace( format!( - "[ERROR][Routine NOT IMPLEMENTED] {} in {}", + "[ROUTINE][Restarted Routine] {} in {}", self_lock.name,self_lock.channel.0 ) .as_str(), Some(format!( - "Routine > start() > (In Tokio Spawn) > {:?}", + "Routine > restart() > {:?}", self_lock.module )), Some(&self_lock.parent_params.msg), ); Log::flush(); - Err("NOT IMPLEMENTED".to_string()) + Ok("Restarted successfully".to_string()) } - pub fn change_channel( - &self, - _channel : Channel + pub async fn change_channel( + &mut self, + channel : Channel ) -> Result<String,String> - // [ ] => 03.27 - WIP - NOT IMPLEMENTED + // [ ] => 03.28 - REVIEW FOR COMPLETION { - // [ ] Think Ideally it should try to + // [x] Think Ideally it should try to // change the target channel of the // internal process too if possible? - Err("NOT IMPLEMENTED".to_string()) + self.channel = channel; + + + let self_rw = Arc::new(RwLock::new(self)); + + let self_lock = self_rw.read().await; + + botlog::trace( + format!( + "[ROUTINE][Change Channel] {} in {}", + self_lock.name,self_lock.channel.0 + ) + .as_str(), + Some(format!( + "Routine > restart() > {:?}", + self_lock.module + )), + Some(&self_lock.parent_params.msg), + ); + + Log::flush(); + + // Err("NOT IMPLEMENTED".to_string()) + Ok("Changed Successfully".to_string()) + } + + + pub async fn set_routine_attributes( + &mut self, + routine_attr : Vec<RoutineAttr> + ) -> Result<String,String> + // [ ] => 03.27 - WIP - NOT IMPLEMENTED + { + // This is way to custom set attributes first + // They will Be Validated before being applied + // IDEALLY the routine also be restarted afterwards externally + + Routine::validate_attr(&routine_attr).await?; + + + let self_rw = Arc::new(RwLock::new(self)); + { + let mut self_lock = self_rw.write().await; + self_lock.routine_attr = routine_attr; + } + + // let self_rw = Arc::new(RwLock::new(self)); + + let self_lock = self_rw.read().await; + + botlog::trace( + format!( + "[ROUTINE][Set Routine Attributes] {} in {}", + self_lock.name,self_lock.channel.0 + ) + .as_str(), + Some(format!( + "Routine > restart() > {:?}", + self_lock.module + )), + Some(&self_lock.parent_params.msg), + ); + + Log::flush(); + + + Ok("Changed Successfully".to_string()) } From 2a1a7f8503e4d8273cae133b7db32c581a3f2cad Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Thu, 28 Mar 2024 04:39:03 -0400 Subject: [PATCH 16/33] ExecBody & routine addl references --- src/core/bot_actions.rs | 2 +- src/core/botinstance.rs | 5 +++ src/core/botmodules.rs | 57 +++++++++++++++++++++--- src/custom/experimental/experiment003.rs | 36 +++++++-------- 4 files changed, 74 insertions(+), 26 deletions(-) diff --git a/src/core/bot_actions.rs b/src/core/bot_actions.rs index 9ff41b5..130be94 100644 --- a/src/core/bot_actions.rs +++ b/src/core/bot_actions.rs @@ -16,7 +16,7 @@ pub type RoutineAR = Arc<RwLock<Routine>>; pub struct ExecBodyParams { pub bot : BotAR, pub msg : PrivmsgMessage, - // pub parent_act : ActAR , + pub parent_act : Option<ActAR> , pub curr_act : ActAR , } diff --git a/src/core/botinstance.rs b/src/core/botinstance.rs index 563856f..86ac8bb 100644 --- a/src/core/botinstance.rs +++ b/src/core/botinstance.rs @@ -404,6 +404,7 @@ impl BotInstance { let params = ExecBodyParams { bot : Arc::clone(&bot), msg : (*msg).clone(), + parent_act : None, curr_act : Arc::clone(&act_clone), }; @@ -461,6 +462,7 @@ impl BotInstance { let params = ExecBodyParams { bot : Arc::clone(&bot), msg : (*msg).clone(), + parent_act : None, curr_act : Arc::clone(&act_clone), }; @@ -491,6 +493,7 @@ impl BotInstance { let params = ExecBodyParams { bot : Arc::clone(&bot), msg : (*msg).clone(), + parent_act : None, curr_act : Arc::clone(&act_clone), }; @@ -516,6 +519,7 @@ impl BotInstance { c.execute(ExecBodyParams { bot : a, msg : msg.clone() , + parent_act : None, curr_act : Arc::clone(&act_clone), }).await; @@ -564,6 +568,7 @@ impl BotInstance { l.execute(ExecBodyParams { bot : a, msg : msg.clone() , + parent_act : None, curr_act : Arc::clone(&act_clone), } ).await; } diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index e320e7f..17c570a 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -637,12 +637,39 @@ pub struct Routine { remaining_iterations : Option<i64> , routine_attr : Vec<RoutineAttr> , pub internal_signal : RoutineSignal , + pub self_routine_ar : Option<RoutineAR> , + pub self_act_ar : Option<ActAR> , } impl Routine { + // pub fn set + // pub async fn refresh_self_ref(self) { + pub async fn refresh_routine_internal(routine_ar : RoutineAR) + { + + /* + Execute after the Routine is constructed + - If not, a start() will also call this + + */ + + // 1. Update the self reference to itself + + let mut mut_lock = routine_ar.write().await; + mut_lock.self_routine_ar = Some(routine_ar.clone()); + + // 2. Update the current self_act_ar + mut_lock.self_act_ar = Some(Arc::new(RwLock::new(BotAction::R(routine_ar.clone())))); + + + + + + } + pub async fn validate_attr(routine_attr : &Vec<RoutineAttr>) -> Result<String,String> @@ -819,6 +846,8 @@ impl Routine { remaining_iterations : None , routine_attr : routine_attr , internal_signal : RoutineSignal::NotStarted , + self_routine_ar : None , + self_act_ar : None , }))) ; @@ -831,6 +860,10 @@ impl Routine { // [ ] => 03.27 - REVIEW FOR COMPLETION { + + // [x] Prep by updating it's own self reference + Routine::refresh_routine_internal(trg_routine_ar.clone()).await; + // [x] Asyncio Spawn likely around here // [x] & Assigns self.join_handle @@ -1005,7 +1038,8 @@ impl Routine { // [x] execution body - trg_routine_ar.read().await.loopbody().await; + // trg_routine_ar.read().await.loopbody().await; + trg_routine_ar.write().await.loopbody().await; { // [x] End of Loop iteration @@ -1100,7 +1134,7 @@ impl Routine { } - async fn loopbody(&self) + async fn loopbody(&mut self) // [x] => 03.27 - COMPLETED { botlog::trace( @@ -1112,10 +1146,23 @@ impl Routine { ); Log::flush(); - - (self.exec_body)( - self.parent_params.clone() + + let self_ar = Arc::new(RwLock::new(self)); + + { + let mut mutlock = self_ar.write().await; + + mutlock.parent_params.parent_act = Some(mutlock.parent_params.curr_act.clone()); + mutlock.parent_params.curr_act = mutlock.self_act_ar.to_owned().unwrap(); + } + + (self_ar.read().await.exec_body)( + self_ar.read().await.parent_params.clone() ).await; + + // (self.exec_body)( + // self.parent_params.clone() + // ).await; } pub async fn stop(&mut self) -> Result<String,String> diff --git a/src/custom/experimental/experiment003.rs b/src/custom/experimental/experiment003.rs index 9b8f91e..343cece 100644 --- a/src/custom/experimental/experiment003.rs +++ b/src/custom/experimental/experiment003.rs @@ -141,28 +141,24 @@ async fn test3_body(params : ExecBodyParams) { if let Ok(newr) = a { + // NOTE : The below is a "Playing aound" feature + // In the below, we're unnecessarily adjusting the ExecBodyParams of the parent + + // To get the reference to the Routine or the BotAction there are now refernces to itself + // [ ] before execute , be sure to adjust curr_act - // let mut params_mut = params.clone(); - let mut params_mut = params; - // let newr_ar = Arc::new(RwLock::new(newr)); + // let mut params_mut = params; let newr_ar = newr.clone(); - params_mut.curr_act = Arc::new(RwLock::new( - BotAction::R(newr_ar.clone()) - )); - - // let a = newr_ar.read().await; - // let rslt = (&*a).start().await; - - // let mut newr_lock = newr_ar.write().await; - - // let rslt = newr_ar.write().await.start().await; + // params_mut.curr_act = Arc::new(RwLock::new( + // BotAction::R(newr_ar.clone()) + // )); - { - newr_ar.write().await.parent_params = params_mut.clone(); - } + // { + // newr_ar.write().await.parent_params = params_mut.clone(); + // } let rslt = Routine::start(newr_ar.clone()).await; @@ -179,12 +175,12 @@ async fn test3_body(params : ExecBodyParams) { rsltstr ).as_str(), Some("experiment003 > test3_body".to_string()), - Some(¶ms_mut.msg), + Some(¶ms.msg), ); Log::flush(); - let bot = Arc::clone(¶ms_mut.bot); + let bot = Arc::clone(¶ms.bot); let botlock = bot.read().await; @@ -193,9 +189,9 @@ async fn test3_body(params : ExecBodyParams) { .botmgrs .chat .say_in_reply_to( - ¶ms_mut.msg, + ¶ms.msg, format!("Routine Result : {:?}",rsltstr), - params_mut.clone() + params.clone() ).await; // [x] Will not be handling JoinHandles here . If immediate abort() handling is required, below is an example that works From 6d3b5eee41f0600ecacf26440f1313b5fbd8649b Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Thu, 28 Mar 2024 11:50:08 -0400 Subject: [PATCH 17/33] routine assigns self reference at construct --- src/core/botmodules.rs | 62 +++++++++++++++++++++++++++++------------- 1 file changed, 43 insertions(+), 19 deletions(-) diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index 17c570a..8e172f6 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -645,30 +645,30 @@ pub struct Routine { impl Routine { - // pub fn set - // pub async fn refresh_self_ref(self) { - pub async fn refresh_routine_internal(routine_ar : RoutineAR) - { + // // pub fn set + // // pub async fn refresh_self_ref(self) { + // pub async fn refresh_routine_internal(routine_ar : RoutineAR) + // { - /* - Execute after the Routine is constructed - - If not, a start() will also call this + // /* + // Execute after the Routine is constructed + // - If not, a start() will also call this - */ + // */ - // 1. Update the self reference to itself + // // 1. Update the self reference to itself - let mut mut_lock = routine_ar.write().await; - mut_lock.self_routine_ar = Some(routine_ar.clone()); + // let mut mut_lock = routine_ar.write().await; + // mut_lock.self_routine_ar = Some(routine_ar.clone()); - // 2. Update the current self_act_ar - mut_lock.self_act_ar = Some(Arc::new(RwLock::new(BotAction::R(routine_ar.clone())))); + // // 2. Update the current self_act_ar + // mut_lock.self_act_ar = Some(Arc::new(RwLock::new(BotAction::R(routine_ar.clone())))); - } + // } pub async fn validate_attr(routine_attr : &Vec<RoutineAttr>) @@ -833,8 +833,8 @@ impl Routine { { Routine::validate_attr(&routine_attr).await?; - - return Ok(Arc::new(RwLock::new(Routine { + + let routine_ar = Arc::new(RwLock::new(Routine { name , module , channel , @@ -848,7 +848,31 @@ impl Routine { internal_signal : RoutineSignal::NotStarted , self_routine_ar : None , self_act_ar : None , - }))) ; + })); + + let mut mut_lock = routine_ar.write().await; + mut_lock.self_routine_ar = Some(routine_ar.clone()); + + // 2. Update the current self_act_ar + mut_lock.self_act_ar = Some(Arc::new(RwLock::new(BotAction::R(routine_ar.clone())))); + + Ok(routine_ar.clone()) + + // return Ok(Arc::new(RwLock::new(Routine { + // name , + // module , + // channel , + // exec_body , + // parent_params , + // join_handle : None , + // start_time : None , + // complete_iterations : 0 , + // remaining_iterations : None , + // routine_attr : routine_attr , + // internal_signal : RoutineSignal::NotStarted , + // self_routine_ar : None , + // self_act_ar : None , + // }))) ; } @@ -861,8 +885,8 @@ impl Routine { { - // [x] Prep by updating it's own self reference - Routine::refresh_routine_internal(trg_routine_ar.clone()).await; + // // [x] Prep by updating it's own self reference + // Routine::refresh_routine_internal(trg_routine_ar.clone()).await; // [x] Asyncio Spawn likely around here // [x] & Assigns self.join_handle From c27dd3b86f38646bebe1d4dd20c8707171df4140 Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Thu, 28 Mar 2024 13:18:02 -0400 Subject: [PATCH 18/33] custom countdown --- src/core/botmodules.rs | 2 +- src/custom/experimental/experiment003.rs | 216 +++++++++++++++++++++++ 2 files changed, 217 insertions(+), 1 deletion(-) diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index 8e172f6..3e6aead 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -634,7 +634,7 @@ pub struct Routine { pub join_handle : Option<Arc<RwLock<JoinHandle<RoutineAR>>>> , start_time : Option<DateTime<Local>> , pub complete_iterations : i64 , - remaining_iterations : Option<i64> , + pub remaining_iterations : Option<i64> , routine_attr : Vec<RoutineAttr> , pub internal_signal : RoutineSignal , pub self_routine_ar : Option<RoutineAR> , diff --git a/src/custom/experimental/experiment003.rs b/src/custom/experimental/experiment003.rs index 343cece..5532dfe 100644 --- a/src/custom/experimental/experiment003.rs +++ b/src/custom/experimental/experiment003.rs @@ -16,6 +16,9 @@ const OF_CMD_CHANNEL:Channel = Channel(String::new()); use casual_logger::Log; use rand::Rng; +use rand::thread_rng; +use rand::rngs::StdRng; +use rand::seq::SliceRandom; use tokio::sync::RwLock; use std::borrow::Borrow; use std::sync::Arc; @@ -50,9 +53,222 @@ pub async fn init(mgr: Arc<ModulesManager>) { botc1.add_to_modmgr(Arc::clone(&mgr)).await; + // 1. Define the BotAction + let botc1 = BotCommand { + module: BotModule(String::from("experiments003")), + command: String::from("countdown"), // command call name + alias: vec![], // String of alternative names + exec_body: actions_util::asyncbox(countdown_chnl_v1), + help: String::from("Test Command tester"), + required_roles: vec![ + BotAdmin, + Mod(OF_CMD_CHANNEL), + ], + }; + + // 2. Add the BotAction to ModulesManager + botc1.add_to_modmgr(Arc::clone(&mgr)).await; + + + } +async fn countdown_chnl_v1(params : ExecBodyParams) { + + botlog::debug( + "[CHILDFN] countdown_chnl() triggered!", + Some("Experiments003 > countdown_chnl()".to_string()), + Some(¶ms.msg), + ); + + + /* + create a fun countdown BotCommand that allows an Elevated Chatter to + -a add channels to target a routine message + -start to start the routine with an input String, that sends a number + of messages to the targeted channels with a countdown, until it + reaches 0 when it sends a cute or funny message + + NOTE : At the moment, I don't have customizable persistence, so I would just use + counters from the Routine itself + */ + + /* + Because of some bot core features are not available, v1.0 of this could be : + [x] 1. Create a Routine & start a routine + [x] 2. Have the routine go through each joined channel randomly and countdown + [x] 3. At the end, say "0, I love you uwu~" in the last chosen channel + */ + + /* + Usage => 03.28 - skipping arguments as functinoality isn't enhanced + + -a <channel> => 03.28 - Not sure if this is possible at the moment? + + -start + + -stop => 03.28 - Not sure if this is possible at the moment? + + */ + + /* + [ ] Functional Use Case + + 1. -a <channel> adds targetted channels + + */ + + // [-] Unwraps arguments from message + + // let (arg1, arg2) = { + + // let mut argv = params.msg.message_text.split(' '); + + // argv.next(); // Skip the command name + + // let arg1 = argv.next(); + + // let arg2 = argv.next(); + + // (arg1, arg2) + // }; + + + + // [ ] 1. Create a Routine & start a routine + + // let parentmodule = params.get_parent_module().await; + let module = params.get_module().await; + let channel = params.get_channel().await; + let routine_attr = vec![ + RoutineAttr::RunOnce + ]; + // let exec_body = actions_util::asyncbox(rtestbody); + let exec_body = actions_util::asyncbox(innertester); // <-- 03.27 - when below is uncommented, this is throwing an issue + + async fn innertester(params : ExecBodyParams) { + + + + let logmsg_botact = match *params.curr_act.read().await { + BotAction::C(_) => "command", + BotAction::R(_) => "routine", + BotAction::L(_) => "listener", + } ; + + + botlog::trace( + format!("Params > Curr_act type : {:?}", logmsg_botact).as_str(), + Some("Experiments003 > countdown_chnl()".to_string()), + Some(¶ms.msg), + ); + Log::flush(); + + let bot = Arc::clone(¶ms.bot); + + let botlock = bot.read().await; + + if let BotAction::R(arr) = &*params.curr_act.read().await { + + let iterleft = arr.read().await.remaining_iterations.unwrap_or(0); + + // [ ] get joined channels + let joinedchannels = botlock.bot_channels.clone(); + + + fn pick_a_channel(chnlvec : Vec<Channel>) -> Channel { + + // More Information : https://docs.rs/rand/0.7.2/rand/seq/trait.SliceRandom.html#tymethod.choose + + let mut rng = thread_rng(); + + // let joinedchannels = botlock.bot_channels.clone(); + (*chnlvec.choose(&mut rng).unwrap()).clone() + } + + let chosen_channel = pick_a_channel(joinedchannels); + + let outmsg = if iterleft == 1 { + format!("{} I love you uwu~",iterleft) + } else { format!("{}",iterleft) }; + + botlock.botmgrs.chat + .say( + // joinedchannels.choose(&mut rng).unwrap().0.clone(), + chosen_channel.0.clone(), + outmsg, + params.clone() + ).await; + + } + + + } + + + + // [ ] setup the routine + if let Ok(newr) = Routine::from( + "Routine Test".to_string(), + module, + channel.unwrap(), + routine_attr, + exec_body, + params.clone() + ).await { + let newr_ar = newr.clone(); + // [ ] start the routine + if let Ok(_) = Routine::start(newr_ar.clone()).await { + + + botlog::debug( + "Successfully started", + Some("experiment003 > countdown_chnl()".to_string()), + Some(¶ms.msg), + ); + + + Log::flush(); + + let bot = Arc::clone(¶ms.bot); + + let botlock = bot.read().await; + + // uses chat.say_in_reply_to() for the bot controls for messages + botlock + .botmgrs + .chat + .say_in_reply_to( + ¶ms.msg, + "Started Routine!".to_string(), + params.clone() + ).await; + + + + } + + + } + + + // botlock + // .botmgrs + // .chat + // .say_in_reply_to( + // ¶ms.msg, + // format!("{:?}",), + // params.clone() + // ).await; + + + +} + + + + async fn test3_body(params : ExecBodyParams) { // println!("testy triggered!"); // NOTE : This test function intends to print (e.g., to stdout) at fn call botlog::debug( From 1b534ebeb7e190cff227217bfa5be816f6e301c8 Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Thu, 28 Mar 2024 13:46:02 -0400 Subject: [PATCH 19/33] fixed routine attr validation logic --- src/core/botmodules.rs | 126 +++++++++++++---------- src/custom/experimental/experiment003.rs | 4 +- 2 files changed, 72 insertions(+), 58 deletions(-) diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index 3e6aead..3c28937 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -691,45 +691,71 @@ impl Routine { // adjust the below for those that are work in progress or that are implemented // - This will allow other functions to validate that it is implemented - // WORK IN PROGRESS VECTOR - Vec<$RoutineAttr> + // // WORK IN PROGRESS VECTOR - Vec<$RoutineAttr> - let wip_attr:Vec<RoutineAttr> = vec![ - RoutineAttr::DelayedStart, - RoutineAttr::ScheduledStart(chrono::offset::Local::now()), - RoutineAttr::LoopDuration(Duration::from_secs(1)), - RoutineAttr::LoopInfinitely, // Note : There's no added implementation for this - RoutineAttr::RunOnce, - RoutineAttr::MaxTimeThreshold(chrono::offset::Local::now()), - RoutineAttr::MaxIterations(1), + // let wip_attr:Vec<RoutineAttr> = vec![ + // RoutineAttr::DelayedStart, + // RoutineAttr::ScheduledStart(chrono::offset::Local::now()), + // RoutineAttr::LoopDuration(Duration::from_secs(1)), + // RoutineAttr::LoopInfinitely, // Note : There's no added implementation for this + // RoutineAttr::RunOnce, + // RoutineAttr::MaxTimeThreshold(chrono::offset::Local::now()), + // RoutineAttr::MaxIterations(1), - ]; + // ]; - let implemented_attr:Vec<RoutineAttr> = vec![ - ]; + // let implemented_attr:Vec<RoutineAttr> = vec![ + // ]; // [x] 2. Built in Logic will check these vectors, and return if Not Implemented - let mut unimplemented = routine_attr.iter() - .filter(|x| { - let inx = x; - wip_attr.iter().filter(|y| matches!(y,i if i == inx)).next().is_none() - || implemented_attr.iter().filter(|y| matches!(y,i if i == inx)).next().is_none() + // let mut unimplemented = routine_attr.iter() + // .filter(|x| { + // let inx = x; + // wip_attr.iter().filter(|y| matches!(y,i if i == inx)).next().is_none() + // && implemented_attr.iter().filter(|y| matches!(y,i if i == inx)).next().is_none() + // } + // ); + + + for given_routine in routine_attr { + + if !matches!(given_routine,RoutineAttr::DelayedStart) + && !matches!(given_routine,RoutineAttr::ScheduledStart(_)) + && !matches!(given_routine,RoutineAttr::LoopDuration(_)) + && !matches!(given_routine,RoutineAttr::LoopInfinitely) + && !matches!(given_routine,RoutineAttr::RunOnce) + && !matches!(given_routine,RoutineAttr::MaxTimeThreshold(_)) + && !matches!(given_routine,RoutineAttr::MaxIterations(_)) + { + botlog::trace( + "[ERROR][Routine Feature NOT IMPLEMENTED]", + Some("Routine > Validate_attr()".to_string()), + None, + ); + + Log::flush(); + + return Err("NOT IMPLEMENTED".to_string()); } - ); - if unimplemented.next().is_some() { + }; - botlog::trace( - "[ERROR][Routine Feature NOT IMPLEMENTED]", - Some("Routine > Validate_attr()".to_string()), - None, - ); + + + // if unimplemented.next().is_some() { + + // botlog::trace( + // "[ERROR][Routine Feature NOT IMPLEMENTED]", + // Some("Routine > Validate_attr()".to_string()), + // None, + // ); - Log::flush(); + // Log::flush(); - return Err("NOT IMPLEMENTED".to_string()); - } + // return Err("NOT IMPLEMENTED".to_string()); + // } @@ -772,40 +798,26 @@ impl Routine { // [x] 4. If all other failure checks above works, ensure one more time that the attribute is implemented // - If not, routine NOT IMPLEMENTED error - if routine_attr.iter() - .filter(|x| { - let inx = x; - wip_attr.iter().filter(|y| matches!(y,i if i == inx)).next().is_none() - || implemented_attr.iter().filter(|y| matches!(y,i if i == inx)).next().is_none() - }) - .next() - .is_none() - { + // if routine_attr.iter() + // .filter(|x| { + // let inx = x; + // wip_attr.iter().filter(|y| matches!(y,i if i == inx)).next().is_none() + // || implemented_attr.iter().filter(|y| matches!(y,i if i == inx)).next().is_none() + // }) + // .next() + // .is_none() + // { - botlog::trace( - "[ERROR][Routine Feature NOT IMPLEMENTED]", - Some("Routine > Validate_attr()".to_string()), - None, - ); + botlog::trace( + "[ERROR][Routine Feature NOT IMPLEMENTED]", + Some("Routine > Validate_attr()".to_string()), + None, + ); - Log::flush(); + Log::flush(); - Ok("Implemented & Validated".to_string()) + Ok("Implemented & Validated".to_string()) - } else { - - - botlog::trace( - "[ERROR][Routine Feature NOT IMPLEMENTED]", - Some("Routine > Validate_attr()".to_string()), - None, - ); - - Log::flush(); - - Err("NOT IMPLEMENTED".to_string()) - - } } diff --git a/src/custom/experimental/experiment003.rs b/src/custom/experimental/experiment003.rs index 5532dfe..66f4f81 100644 --- a/src/custom/experimental/experiment003.rs +++ b/src/custom/experimental/experiment003.rs @@ -142,7 +142,9 @@ async fn countdown_chnl_v1(params : ExecBodyParams) { let module = params.get_module().await; let channel = params.get_channel().await; let routine_attr = vec![ - RoutineAttr::RunOnce + // RoutineAttr::RunOnce + RoutineAttr::MaxIterations(5), + RoutineAttr::LoopDuration(Duration::from_secs(1)) ]; // let exec_body = actions_util::asyncbox(rtestbody); let exec_body = actions_util::asyncbox(innertester); // <-- 03.27 - when below is uncommented, this is throwing an issue From 26f67787d7ce54157a16ba454c3760abc4c67019 Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Thu, 28 Mar 2024 15:07:24 -0400 Subject: [PATCH 20/33] addl debugging --- src/core/botmodules.rs | 2 +- src/custom/experimental/experiment003.rs | 49 ++++++++++++++++++++++-- 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index 3c28937..3da6122 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -795,7 +795,7 @@ impl Routine { - // [x] 4. If all other failure checks above works, ensure one more time that the attribute is implemented + // [x] 4. If all other failure checks above works, ensure one more time that the atstribute is implemented // - If not, routine NOT IMPLEMENTED error // if routine_attr.iter() diff --git a/src/custom/experimental/experiment003.rs b/src/custom/experimental/experiment003.rs index 66f4f81..d40d7ab 100644 --- a/src/custom/experimental/experiment003.rs +++ b/src/custom/experimental/experiment003.rs @@ -21,6 +21,7 @@ use rand::rngs::StdRng; use rand::seq::SliceRandom; use tokio::sync::RwLock; use std::borrow::Borrow; +use std::borrow::BorrowMut; use std::sync::Arc; use crate::core::bot_actions::ExecBodyParams; @@ -173,24 +174,63 @@ async fn countdown_chnl_v1(params : ExecBodyParams) { if let BotAction::R(arr) = &*params.curr_act.read().await { - let iterleft = arr.read().await.remaining_iterations.unwrap_or(0); + botlog::trace( + "Before loading remaining iterations", + Some("Experiments003 > countdown_chnl()".to_string()), + None, + ); + Log::flush(); + + + // let iterleft = arr.read().await.remaining_iterations.unwrap_or(0); + + // let iterleft = if arr.read().await.remaining_iterations.is_none() { 0i64 } + // else { arr.read().await.remaining_iterations.unwrap() }; + let iterleft = match arr.read().await.remaining_iterations { + None => 0, + Some(a) => a, + }; + + + botlog::trace( + "after loading remaining iterations", + Some("Experiments003 > countdown_chnl()".to_string()), + None, + ); + Log::flush(); // [ ] get joined channels let joinedchannels = botlock.bot_channels.clone(); fn pick_a_channel(chnlvec : Vec<Channel>) -> Channel { + + + botlog::trace( + "In Pick_a_Channel()", + Some("Experiments003 > countdown_chnl()".to_string()), + None, + ); + Log::flush(); // More Information : https://docs.rs/rand/0.7.2/rand/seq/trait.SliceRandom.html#tymethod.choose let mut rng = thread_rng(); - // let joinedchannels = botlock.bot_channels.clone(); + // let joinedchannels = botlock.bot_channels.clone(); (*chnlvec.choose(&mut rng).unwrap()).clone() } + let chosen_channel = pick_a_channel(joinedchannels); + botlog::trace( + format!("Picked a channel: {:?}", chosen_channel).as_str(), + Some("Experiments003 > countdown_chnl()".to_string()), + Some(¶ms.msg), + ); + Log::flush(); + let outmsg = if iterleft == 1 { format!("{} I love you uwu~",iterleft) } else { format!("{}",iterleft) }; @@ -247,7 +287,10 @@ async fn countdown_chnl_v1(params : ExecBodyParams) { params.clone() ).await; - + // let jhandle = newr.clone().read().await.join_handle.clone().unwrap(); + // let a = jhandle.write().await; + // a. + // sleep(Duration::from_secs(300)).await; } From 5c35ad114a7df9628046775a4334ad930e19c83f Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Thu, 28 Mar 2024 17:52:43 -0400 Subject: [PATCH 21/33] ISSUE - commented out problem code? --- src/custom/experimental/experiment003.rs | 32 ++++++++++++------------ 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/custom/experimental/experiment003.rs b/src/custom/experimental/experiment003.rs index d40d7ab..c881d90 100644 --- a/src/custom/experimental/experiment003.rs +++ b/src/custom/experimental/experiment003.rs @@ -184,12 +184,12 @@ async fn countdown_chnl_v1(params : ExecBodyParams) { // let iterleft = arr.read().await.remaining_iterations.unwrap_or(0); - // let iterleft = if arr.read().await.remaining_iterations.is_none() { 0i64 } - // else { arr.read().await.remaining_iterations.unwrap() }; - let iterleft = match arr.read().await.remaining_iterations { - None => 0, - Some(a) => a, - }; + // // let iterleft = if arr.read().await.remaining_iterations.is_none() { 0i64 } + // // else { arr.read().await.remaining_iterations.unwrap() }; + // let iterleft = match arr.read().await.remaining_iterations { + // None => 0, + // Some(a) => a, + // }; botlog::trace( @@ -231,17 +231,17 @@ async fn countdown_chnl_v1(params : ExecBodyParams) { ); Log::flush(); - let outmsg = if iterleft == 1 { - format!("{} I love you uwu~",iterleft) - } else { format!("{}",iterleft) }; + // let outmsg = if iterleft == 1 { + // format!("{} I love you uwu~",iterleft) + // } else { format!("{}",iterleft) }; - botlock.botmgrs.chat - .say( - // joinedchannels.choose(&mut rng).unwrap().0.clone(), - chosen_channel.0.clone(), - outmsg, - params.clone() - ).await; + // botlock.botmgrs.chat + // .say( + // // joinedchannels.choose(&mut rng).unwrap().0.clone(), + // chosen_channel.0.clone(), + // outmsg, + // params.clone() + // ).await; } From 66195138f83cc6443dbaccd349d0fdf2183609d3 Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Thu, 28 Mar 2024 20:21:49 -0400 Subject: [PATCH 22/33] corrected error with validate_attr --- src/core/botmodules.rs | 61 +++++++++++++++++------- src/custom/experimental/experiment003.rs | 10 ++++ 2 files changed, 55 insertions(+), 16 deletions(-) diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index 3da6122..2cfbb77 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -580,7 +580,7 @@ impl BotActionTrait for Listener { } // #[derive(Debug, PartialEq, Eq, Hash, Clone)] -#[derive(PartialEq, Eq, Hash)] +#[derive(Debug, PartialEq, Eq, Hash)] pub enum RoutineAttr { DelayedStart, ScheduledStart(DateTime<Local>), // Scheduled Date (if any) after which, if not started, may trigger @@ -718,31 +718,60 @@ impl Routine { // } // ); + let mut attribute_supported = false; for given_routine in routine_attr { - if !matches!(given_routine,RoutineAttr::DelayedStart) - && !matches!(given_routine,RoutineAttr::ScheduledStart(_)) - && !matches!(given_routine,RoutineAttr::LoopDuration(_)) - && !matches!(given_routine,RoutineAttr::LoopInfinitely) - && !matches!(given_routine,RoutineAttr::RunOnce) - && !matches!(given_routine,RoutineAttr::MaxTimeThreshold(_)) - && !matches!(given_routine,RoutineAttr::MaxIterations(_)) + // if !matches!(given_routine,RoutineAttr::DelayedStart) + // && !matches!(given_routine,RoutineAttr::ScheduledStart(_)) + // && !matches!(given_routine,RoutineAttr::LoopDuration(_)) + // && !matches!(given_routine,RoutineAttr::LoopInfinitely) + // && !matches!(given_routine,RoutineAttr::RunOnce) + // && !matches!(given_routine,RoutineAttr::MaxTimeThreshold(_)) + // && !matches!(given_routine,RoutineAttr::MaxIterations(_)) + if matches!(given_routine,RoutineAttr::DelayedStart) + || matches!(given_routine,RoutineAttr::ScheduledStart(_)) + || matches!(given_routine,RoutineAttr::LoopDuration(_)) + || matches!(given_routine,RoutineAttr::LoopInfinitely) + || matches!(given_routine,RoutineAttr::RunOnce) + || matches!(given_routine,RoutineAttr::MaxTimeThreshold(_)) + || matches!(given_routine,RoutineAttr::MaxIterations(_)) + { - botlog::trace( - "[ERROR][Routine Feature NOT IMPLEMENTED]", - Some("Routine > Validate_attr()".to_string()), - None, - ); - Log::flush(); + attribute_supported = true; - return Err("NOT IMPLEMENTED".to_string()); } }; + if !attribute_supported { + botlog::trace( + "[ERROR][Routine Feature NOT IMPLEMENTED]", + Some("Routine > Validate_attr()".to_string()), + None, + ); + + Log::flush(); + + botlog::trace( + format!( + "[ERROR][Routine Feature NOT IMPLEMENTED] > Problem Routine - {:?}" + ,routine_attr).as_str(), + Some("Routine > Validate_attr()".to_string()), + None, + ); + + Log::flush(); + + return Err("NOT IMPLEMENTED".to_string()); + } + + + + + // if unimplemented.next().is_some() { @@ -809,7 +838,7 @@ impl Routine { // { botlog::trace( - "[ERROR][Routine Feature NOT IMPLEMENTED]", + "[OK][Implemented & Validated]", Some("Routine > Validate_attr()".to_string()), None, ); diff --git a/src/custom/experimental/experiment003.rs b/src/custom/experimental/experiment003.rs index c881d90..a37066f 100644 --- a/src/custom/experimental/experiment003.rs +++ b/src/custom/experimental/experiment003.rs @@ -191,6 +191,16 @@ async fn countdown_chnl_v1(params : ExecBodyParams) { // Some(a) => a, // }; + // let routine_lock = arr.read().await; + // if let Some(a) = routine_lock.remaining_iterations.clone() { + // println!("Remaining iterations > {}",a) + // } + + { + let routine_lock = arr.write().await; + let a = routine_lock.remaining_iterations; + println!("remaining iterations : {:?}", a); +} botlog::trace( "after loading remaining iterations", From b5e95668a514fd7e59190b5d161a1cb346947848 Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Fri, 29 Mar 2024 09:03:16 -0400 Subject: [PATCH 23/33] ISSUE - potential lock issue --- src/core/botmodules.rs | 4 +- src/custom/experimental/experiment003.rs | 127 +++++++++++++++-------- 2 files changed, 87 insertions(+), 44 deletions(-) diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index 2cfbb77..f4dfb18 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -1104,7 +1104,9 @@ impl Routine { // [x] execution body // trg_routine_ar.read().await.loopbody().await; - trg_routine_ar.write().await.loopbody().await; + { + trg_routine_ar.write().await.loopbody().await; + } { // [x] End of Loop iteration diff --git a/src/custom/experimental/experiment003.rs b/src/custom/experimental/experiment003.rs index a37066f..41c1d65 100644 --- a/src/custom/experimental/experiment003.rs +++ b/src/custom/experimental/experiment003.rs @@ -152,34 +152,44 @@ async fn countdown_chnl_v1(params : ExecBodyParams) { async fn innertester(params : ExecBodyParams) { - + { + let curract_guard = params.curr_act.read().await; + - let logmsg_botact = match *params.curr_act.read().await { - BotAction::C(_) => "command", - BotAction::R(_) => "routine", - BotAction::L(_) => "listener", - } ; + // let logmsg_botact = match *params.curr_act.read().await { + + let logmsg_botact = match *curract_guard { + BotAction::C(_) => "command", + BotAction::R(_) => "routine", + BotAction::L(_) => "listener", + } ; - botlog::trace( - format!("Params > Curr_act type : {:?}", logmsg_botact).as_str(), - Some("Experiments003 > countdown_chnl()".to_string()), - Some(¶ms.msg), - ); - Log::flush(); - - let bot = Arc::clone(¶ms.bot); - - let botlock = bot.read().await; - - if let BotAction::R(arr) = &*params.curr_act.read().await { - botlog::trace( - "Before loading remaining iterations", + format!("Params > Curr_act type : {:?}", logmsg_botact).as_str(), Some("Experiments003 > countdown_chnl()".to_string()), - None, + Some(¶ms.msg), ); Log::flush(); + } + + { + let bot = Arc::clone(¶ms.bot); + let botlock = bot.read().await; + + let curract_guard = params.curr_act.write().await; + + // let routine_lock = arr.write().await; + + if let BotAction::R(arr) = &*curract_guard { + // if let BotAction::R(arr) = &*params.curr_act.read().await { + + botlog::trace( + "Before loading remaining iterations", + Some("Experiments003 > countdown_chnl()".to_string()), + None, + ); + Log::flush(); // let iterleft = arr.read().await.remaining_iterations.unwrap_or(0); @@ -197,10 +207,10 @@ async fn countdown_chnl_v1(params : ExecBodyParams) { // } { - let routine_lock = arr.write().await; - let a = routine_lock.remaining_iterations; - println!("remaining iterations : {:?}", a); -} + let routine_lock = arr.write().await; + let a = routine_lock.remaining_iterations; + println!("remaining iterations : {:?}", a); + } botlog::trace( "after loading remaining iterations", @@ -251,9 +261,12 @@ async fn countdown_chnl_v1(params : ExecBodyParams) { // chosen_channel.0.clone(), // outmsg, // params.clone() + + // ).await; } + } } @@ -361,27 +374,55 @@ async fn test3_body(params : ExecBodyParams) { async fn rtestbody(params : ExecBodyParams) { - let logmsg_botact = match *params.curr_act.read().await { - BotAction::C(_) => "command", - BotAction::R(_) => "routine", - BotAction::L(_) => "listener", - } ; + let guard = params.curr_act.read().await; + { + let logmsg_botact = match *guard { + BotAction::C(_) => "command", + BotAction::R(_) => "routine", + BotAction::L(_) => "listener", + } ; - botlog::trace( - format!("Params > Curr_act type : {:?}", logmsg_botact).as_str(), - Some("Experiments003 > test3 command body".to_string()), - Some(¶ms.msg), - ); - Log::flush(); + botlog::trace( + format!("Params > Curr_act type : {:?}", logmsg_botact).as_str(), + Some("Experiments003 > test3 command body".to_string()), + Some(¶ms.msg), + ); + Log::flush(); + } - if let BotAction::R(arr) = &*params.curr_act.read().await { - for curriter in 0..5 { - println!("tester - Routine - Completed Iterations : {}", - arr.read().await.complete_iterations); - println!("tester - Custom Loop - Completed Iterations : {}", - curriter); - sleep(Duration::from_secs_f64(0.5)).await; + + { + let logmsg_botact = match *guard { + BotAction::C(_) => "command 2", + BotAction::R(_) => "routine 2", + BotAction::L(_) => "listener 2", + } ; + + botlog::trace( + format!("Params > Curr_act type : {:?}", logmsg_botact).as_str(), + Some("Experiments003 > test3 command body".to_string()), + Some(¶ms.msg), + ); + Log::flush(); + } + + + { + println!("Critical code area start"); // <= 03.29 - This is printed + if let BotAction::R(c) = &*guard { + println!("{:?}",c.read().await.channel); } + println!("Critical code area end"); // <= 03.29 - ISSUE This is NOT printed + + // if let BotAction::R(arr) = &*params.curr_act.read().await { + // for curriter in 0..5 { + // println!("tester - Routine - Completed Iterations : {}", + // arr.read().await.complete_iterations); + // println!("tester - Custom Loop - Completed Iterations : {}", + // curriter); + // sleep(Duration::from_secs_f64(0.5)).await; + // } + // } } } From 9d94328cd67dce4d5c9796f53472d539be0f4073 Mon Sep 17 00:00:00 2001 From: mzntori <mzntori@proton.me> Date: Fri, 29 Mar 2024 21:05:21 +0100 Subject: [PATCH 24/33] mark call that locks execbody from using that routine --- src/core/botmodules.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index f4dfb18..0dba823 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -1223,10 +1223,15 @@ impl Routine { mutlock.parent_params.curr_act = mutlock.self_act_ar.to_owned().unwrap(); } + dbg!("before"); + + // `self_ar` is the routine you want to read in the execbody i think, but its used to call that execbody. + // So execbody waits for itself to finish. (self_ar.read().await.exec_body)( self_ar.read().await.parent_params.clone() ).await; - + + dbg!("after"); // (self.exec_body)( // self.parent_params.clone() // ).await; From fcf4f3f7cfe6c94eefdb3883bb3e06e52d9895a6 Mon Sep 17 00:00:00 2001 From: mzntori <mzntori@proton.me> Date: Fri, 29 Mar 2024 21:06:48 +0100 Subject: [PATCH 25/33] add debug implementations that helped (kinda) --- src/core/bot_actions.rs | 2 +- src/core/botinstance.rs | 3 ++- src/core/botmodules.rs | 34 +++++++++++++++++++++++++++++++++- src/core/chat.rs | 2 +- src/core/identity.rs | 2 +- 5 files changed, 38 insertions(+), 5 deletions(-) diff --git a/src/core/bot_actions.rs b/src/core/bot_actions.rs index 130be94..c7ec0c5 100644 --- a/src/core/bot_actions.rs +++ b/src/core/bot_actions.rs @@ -12,7 +12,7 @@ pub type BotAR = Arc<RwLock<BotInstance>>; pub type ActAR = Arc<RwLock<BotAction>>; pub type RoutineAR = Arc<RwLock<Routine>>; -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct ExecBodyParams { pub bot : BotAR, pub msg : PrivmsgMessage, diff --git a/src/core/botinstance.rs b/src/core/botinstance.rs index 86ac8bb..2c06cea 100644 --- a/src/core/botinstance.rs +++ b/src/core/botinstance.rs @@ -40,7 +40,7 @@ pub struct Channel(pub String); use super::bot_actions::ExecBodyParams; use super::botmodules::StatusType; -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct BotManagers { pub identity: Arc<RwLock<IdentityManager>>, pub chat: Chat, @@ -70,6 +70,7 @@ impl<T: Clone> ArcBox<T> { } } +#[derive(Debug)] pub struct BotInstance { pub prefix: char, pub bot_channel: Channel, diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index 0dba823..32e669f 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -28,6 +28,7 @@ use core::panic; use std::borrow::Borrow; use std::borrow::BorrowMut; use std::collections::HashMap; +use std::fmt::{Debug, Formatter}; use std::ops::DerefMut; use std::sync::Arc; @@ -470,6 +471,7 @@ pub enum StatusType { Disabled(StatusLvl), } +#[derive(Debug)] pub enum BotAction { C(BotCommand), L(Listener), @@ -532,6 +534,12 @@ impl BotActionTrait for BotCommand { } } +impl Debug for BotCommand { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "{:?} {:?} {:?} {:?} {:?}", self.module, self.command, self.alias, self.help, self.required_roles) + } +} + pub struct Listener { pub module: BotModule, pub name: String, @@ -579,6 +587,12 @@ impl BotActionTrait for Listener { } } +impl Debug for Listener { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "{:?} {:?} {:?}", self.module, self.name, self.help) + } +} + // #[derive(Debug, PartialEq, Eq, Hash, Clone)] #[derive(Debug, PartialEq, Eq, Hash)] pub enum RoutineAttr { @@ -617,6 +631,7 @@ pub enum RoutineAttr { */ // For some key statuses and in particular Stopping to Gracefully stop +#[derive(Debug)] pub enum RoutineSignal { Stopping, // Gracefully Stopping Stopped, // When cancelling or aborting, this also is represented by Stopped @@ -624,7 +639,6 @@ pub enum RoutineSignal { NotStarted, } -// #[derive(Debug)] pub struct Routine { pub name : String , pub module : BotModule , // from() can determine this if passed parents_params @@ -641,6 +655,23 @@ pub struct Routine { pub self_act_ar : Option<ActAR> , } +// implement Debug manually witouth `exec_body` since you cant debug `ExecBody`. +impl Debug for Routine { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "{:?}", self.name)?; + write!(f, "{:?}", self.module)?; + write!(f, "{:?}", self.channel)?; + write!(f, "{:?}", self.parent_params)?; + write!(f, "{:?}", self.join_handle)?; + write!(f, "{:?}", self.start_time)?; + write!(f, "{:?}", self.complete_iterations)?; + write!(f, "{:?}", self.remaining_iterations)?; + write!(f, "{:?}", self.routine_attr)?; + write!(f, "{:?}", self.internal_signal)?; + write!(f, "{:?}", self.self_routine_ar)?; + write!(f, "{:?}", self.self_act_ar) + } +} impl Routine { @@ -1477,6 +1508,7 @@ impl Routine { type StatusdbEntry = (ModGroup, Vec<StatusType>); type ModuleActions = Vec<Arc<RwLock<BotAction>>>; +#[derive(Debug)] pub struct ModulesManager { statusdb: Arc<RwLock<HashMap<BotModule, StatusdbEntry>>>, pub botactions: Arc<RwLock<HashMap<BotModule, ModuleActions>>>, diff --git a/src/core/chat.rs b/src/core/chat.rs index a83bd8c..275ef3b 100644 --- a/src/core/chat.rs +++ b/src/core/chat.rs @@ -27,7 +27,7 @@ use super::identity; use async_recursion::async_recursion; -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct Chat { pub ratelimiters: Arc<Mutex<HashMap<Channel, RateLimiter>>>, // used to limit messages sent per channel pub client: TwitchIRCClient<TCPTransport<TLS>, StaticLoginCredentials>, diff --git a/src/core/identity.rs b/src/core/identity.rs index e1500eb..7a9e579 100644 --- a/src/core/identity.rs +++ b/src/core/identity.rs @@ -698,7 +698,7 @@ pub enum Permissible { type UserRolesDB = HashMap<String, Arc<RwLock<Vec<UserRole>>>>; -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct IdentityManager { special_roles_users: Arc<RwLock<UserRolesDB>>, } From a38c84b8f456cfb290c2d8ce9a7c51b8c8352900 Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Fri, 29 Mar 2024 23:51:41 -0400 Subject: [PATCH 26/33] smol --- src/core/bot_actions.rs | 4 +-- src/core/botmodules.rs | 34 +++++++++++++++--- src/custom/experimental/experiment003.rs | 44 ++++++++++++++++++++---- 3 files changed, 67 insertions(+), 15 deletions(-) diff --git a/src/core/bot_actions.rs b/src/core/bot_actions.rs index c7ec0c5..235637e 100644 --- a/src/core/bot_actions.rs +++ b/src/core/bot_actions.rs @@ -52,9 +52,6 @@ impl ExecBodyParams { pub async fn get_channel(&self) -> Option<Channel> { - // THIS IS INCORRECT - BELOW MAY BE PULLING THE PARENT BOTACTION - // NOT THE CURRENT BOT ACTION - let curr_act = Arc::clone(&self.curr_act); let parent_act_lock = curr_act.read().await; @@ -74,6 +71,7 @@ impl ExecBodyParams { BotAction::R(r) => { // let temp = r.module.clone(); // Some(temp) + dbg!("Core > ExecBodyParams > GetChannels - routine identified"); Some(r.read().await.channel.clone()) } // _ => None diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index 32e669f..b3c8a5f 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -1232,6 +1232,10 @@ impl Routine { } + // pub async fn execute(routine:&Routine, params : ExecBodyParams) { + // (routine.exec_body)(params).await; + // } + async fn loopbody(&mut self) // [x] => 03.27 - COMPLETED { @@ -1254,15 +1258,35 @@ impl Routine { mutlock.parent_params.curr_act = mutlock.self_act_ar.to_owned().unwrap(); } - dbg!("before"); + dbg!("Core > Before Guards"); // `self_ar` is the routine you want to read in the execbody i think, but its used to call that execbody. // So execbody waits for itself to finish. - (self_ar.read().await.exec_body)( - self_ar.read().await.parent_params.clone() - ).await; + // (self_ar.read().await.exec_body)( + // self_ar.read().await.parent_params.clone() + // ).await; - dbg!("after"); + let parent_params = { + let guard1 = self_ar.read().await; + + let parent_params = guard1.parent_params.clone(); + drop(guard1); + parent_params + }; + + dbg!("Core > Guarding & Executing Child Execution Body"); + + { + let guard2 = self_ar.read().await; + (guard2.exec_body)(parent_params).await; + drop(guard2); + + } + // (self_ar.read().await.exec_body)( + // parent_params + // ).await; + + dbg!("Core > After Execution Body is completed"); // (self.exec_body)( // self.parent_params.clone() // ).await; diff --git a/src/custom/experimental/experiment003.rs b/src/custom/experimental/experiment003.rs index 41c1d65..fdcdde6 100644 --- a/src/custom/experimental/experiment003.rs +++ b/src/custom/experimental/experiment003.rs @@ -374,9 +374,9 @@ async fn test3_body(params : ExecBodyParams) { async fn rtestbody(params : ExecBodyParams) { - let guard = params.curr_act.read().await; + let guard1 = params.curr_act.read().await; { - let logmsg_botact = match *guard { + let logmsg_botact = match *guard1 { BotAction::C(_) => "command", BotAction::R(_) => "routine", BotAction::L(_) => "listener", @@ -392,7 +392,7 @@ async fn test3_body(params : ExecBodyParams) { { - let logmsg_botact = match *guard { + let logmsg_botact = match &*guard1 { BotAction::C(_) => "command 2", BotAction::R(_) => "routine 2", BotAction::L(_) => "listener 2", @@ -406,14 +406,44 @@ async fn test3_body(params : ExecBodyParams) { Log::flush(); } + // drop(guard1); + { + dbg!("Custom > within Child Custom fn - Before Critical area"); println!("Critical code area start"); // <= 03.29 - This is printed - if let BotAction::R(c) = &*guard { - println!("{:?}",c.read().await.channel); - } - println!("Critical code area end"); // <= 03.29 - ISSUE This is NOT printed + // if let BotAction::R(c) = &*guard { + // println!("{:?}",c.read().await.channel); + // } + + // let routine_channel = if let BotAction::R(c) = &*guard1 { + // dbg!("Custom > within Child Custom fn - During Critical area > Routine Guard "); + // let routineguard = c.read().await; + // Some(routineguard.channel.clone()); + // } else { + // None + // }; + + + // let chnl = match &*guard1 { + // BotAction::R(arr) => { + // dbg!("Custom > within Child Custom fn - During Critical area > Before Routine Guard "); + // let routineguard = arr.read().await; + // dbg!("Custom > within Child Custom fn - During Critical area > After Routine Guard "); + // Some(routineguard.channel.clone()) + // }, + // BotAction::C(_) | BotAction::L(_) => None , + // } ; + + let chnl = params.get_channel().await; + dbg!("Custom > within Child Custom fn - after GetChannel"); + println!("{:?}",chnl); + + + println!("Critical code area end"); // <= 03.29 - ISSUE This is NOT printed + dbg!("Custom > within Child Custom fn - Before Critical area"); + // if let BotAction::R(arr) = &*params.curr_act.read().await { // for curriter in 0..5 { // println!("tester - Routine - Completed Iterations : {}", From 0625e7f0911652dd0b49fecf79614a4cfe18eec2 Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Sat, 30 Mar 2024 14:26:06 -0400 Subject: [PATCH 27/33] adding tokio-console --- .cargo/config.toml | 3 + Cargo.lock | 1122 +++++++++++++++++++++++++++++++++++++++++++- Cargo.toml | 4 +- src/main.rs | 3 + 4 files changed, 1117 insertions(+), 15 deletions(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index 46ba45d..365b0e8 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,4 +1,7 @@ +[build] +rustflags = ["--cfg", "tokio_unstable"] + [env] # Based on https://doc.rust-lang.org/cargo/reference/config.html OtherBots = "Supibot,buttsbot,PotatBotat,StreamElements,yuumeibot" diff --git a/Cargo.lock b/Cargo.lock index da35376..296b771 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -41,6 +41,12 @@ dependencies = [ "libc", ] +[[package]] +name = "anyhow" +version = "1.0.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" + [[package]] name = "async-recursion" version = "1.1.0" @@ -49,7 +55,29 @@ checksum = "30c5ef0ede93efbf733c1a727f3b6b5a1060bbedd5600183e66f6e4be4af0ec5" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.50", +] + +[[package]] +name = "async-stream" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.50", ] [[package]] @@ -60,7 +88,18 @@ checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.50", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi 0.1.19", + "libc", + "winapi", ] [[package]] @@ -69,6 +108,51 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "axum" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" +dependencies = [ + "async-trait", + "axum-core", + "bitflags 1.3.2", + "bytes", + "futures-util", + "http", + "http-body", + "hyper", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "sync_wrapper", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "mime", + "rustversion", + "tower-layer", + "tower-service", +] + [[package]] name = "backtrace" version = "0.3.69" @@ -84,6 +168,12 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + [[package]] name = "bitflags" version = "1.3.2" @@ -102,12 +192,24 @@ version = "3.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ea184aa71bb362a1157c896979544cc23974e08fd265f29ea96b59f0b4a555b" +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + [[package]] name = "bytes" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +[[package]] +name = "cassowary" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" + [[package]] name = "casual_logger" version = "0.6.5" @@ -145,6 +247,119 @@ dependencies = [ "windows-targets 0.52.3", ] +[[package]] +name = "clap" +version = "3.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" +dependencies = [ + "atty", + "bitflags 1.3.2", + "clap_derive", + "clap_lex", + "indexmap 1.9.3", + "once_cell", + "strsim", + "termcolor", + "textwrap", +] + +[[package]] +name = "clap_complete" +version = "3.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f7a2e0a962c45ce25afce14220bc24f9dade0a1787f185cecf96bfba7847cd8" +dependencies = [ + "clap", +] + +[[package]] +name = "clap_derive" +version = "3.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae6371b8bdc8b7d3959e9cf7b22d4435ef3e79e138688421ec654acf8c81b008" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "clap_lex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +dependencies = [ + "os_str_bytes", +] + +[[package]] +name = "color-eyre" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55146f5e46f237f7423d74111267d4597b59b0dad0ffaf7303bce9945d843ad5" +dependencies = [ + "backtrace", + "color-spantrace", + "eyre", + "indenter", + "once_cell", + "owo-colors", + "tracing-error", + "url", +] + +[[package]] +name = "color-spantrace" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd6be1b2a7e382e2b98b43b2adcca6bb0e465af0bdd38123873ae61eb17a72c2" +dependencies = [ + "once_cell", + "owo-colors", + "tracing-core", + "tracing-error", +] + +[[package]] +name = "console-api" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd326812b3fd01da5bb1af7d340d0d555fd3d4b641e7f1dfcf5962a902952787" +dependencies = [ + "futures-core", + "prost", + "prost-types", + "tonic", + "tracing-core", +] + +[[package]] +name = "console-subscriber" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7481d4c57092cd1c19dd541b92bdce883de840df30aa5d03fd48a3935c01842e" +dependencies = [ + "console-api", + "crossbeam-channel", + "crossbeam-utils", + "futures-task", + "hdrhistogram", + "humantime", + "prost-types", + "serde", + "serde_json", + "thread_local", + "tokio", + "tokio-stream", + "tonic", + "tracing", + "tracing-core", + "tracing-subscriber", +] + [[package]] name = "core-foundation" version = "0.9.4" @@ -161,6 +376,76 @@ version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +[[package]] +name = "crc32fast" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" + +[[package]] +name = "crossterm" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a84cda67535339806297f1b331d6dd6320470d2a0fe65381e79ee9e156dd3d13" +dependencies = [ + "bitflags 1.3.2", + "crossterm_winapi", + "futures-core", + "libc", + "mio", + "parking_lot", + "signal-hook", + "signal-hook-mio", + "winapi", +] + +[[package]] +name = "crossterm_winapi" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" +dependencies = [ + "winapi", +] + +[[package]] +name = "dirs" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + [[package]] name = "dotenv" version = "0.15.0" @@ -182,9 +467,15 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn", + "syn 2.0.50", ] +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + [[package]] name = "errno" version = "0.3.8" @@ -195,12 +486,38 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "eyre" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" +dependencies = [ + "indenter", + "once_cell", +] + [[package]] name = "fastrand" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +[[package]] +name = "flate2" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + [[package]] name = "forcebot_rs" version = "0.1.0" @@ -209,10 +526,12 @@ dependencies = [ "async-trait", "casual_logger", "chrono", + "console-subscriber", "dotenv", "futures", "rand", "tokio", + "tokio-console", "twitch-irc", ] @@ -231,6 +550,15 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + [[package]] name = "futures" version = "0.3.30" @@ -287,7 +615,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.50", ] [[package]] @@ -337,12 +665,147 @@ version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +[[package]] +name = "h2" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fbd2820c5e49886948654ab546d0688ff24530286bdcf8fca3cefb16d4618eb" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap 2.2.6", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" + +[[package]] +name = "hdrhistogram" +version = "7.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "765c9198f173dd59ce26ff9f95ef0aafd0a0fe01fb9d72841bc5066a4c06511d" +dependencies = [ + "base64", + "byteorder", + "flate2", + "nom", + "num-traits", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + [[package]] name = "hermit-abi" version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "379dada1584ad501b383485dd706b8afb7a70fcbc7f4da7d780638a5a6124a60" +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "hyper" +version = "0.14.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-timeout" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" +dependencies = [ + "hyper", + "pin-project-lite", + "tokio", + "tokio-io-timeout", +] + [[package]] name = "iana-time-zone" version = "0.1.60" @@ -366,6 +829,57 @@ dependencies = [ "cc", ] +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + +[[package]] +name = "indexmap" +version = "2.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +dependencies = [ + "equivalent", + "hashbrown 0.14.3", +] + +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + [[package]] name = "js-sys" version = "0.3.68" @@ -387,6 +901,17 @@ version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +[[package]] +name = "libredox" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +dependencies = [ + "bitflags 2.4.2", + "libc", + "redox_syscall", +] + [[package]] name = "linux-raw-sys" version = "0.4.13" @@ -409,12 +934,39 @@ version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + [[package]] name = "memchr" version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" version = "0.7.2" @@ -431,6 +983,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" dependencies = [ "libc", + "log", "wasi", "windows-sys 0.48.0", ] @@ -453,6 +1006,26 @@ dependencies = [ "tempfile", ] +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + [[package]] name = "num-traits" version = "0.2.18" @@ -468,7 +1041,7 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.8", "libc", ] @@ -510,7 +1083,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.50", ] [[package]] @@ -531,6 +1104,24 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "os_str_bytes" +version = "6.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "owo-colors" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" + [[package]] name = "parking_lot" version = "0.12.1" @@ -554,6 +1145,32 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.50", +] + [[package]] name = "pin-project-lite" version = "0.2.13" @@ -578,6 +1195,30 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + [[package]] name = "proc-macro2" version = "1.0.78" @@ -587,6 +1228,38 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "prost" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-derive" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" +dependencies = [ + "anyhow", + "itertools", + "proc-macro2", + "quote", + "syn 2.0.50", +] + +[[package]] +name = "prost-types" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "193898f59edcf43c26227dcd4c8427f00d99d61e95dcde58dabd49fa291d470e" +dependencies = [ + "prost", +] + [[package]] name = "quote" version = "1.0.35" @@ -626,6 +1299,19 @@ dependencies = [ "getrandom", ] +[[package]] +name = "ratatui" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcc0d032bccba900ee32151ec0265667535c230169f5a011154cdcd984e16829" +dependencies = [ + "bitflags 1.3.2", + "cassowary", + "crossterm", + "unicode-segmentation", + "unicode-width", +] + [[package]] name = "redox_syscall" version = "0.4.1" @@ -635,6 +1321,17 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "redox_users" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" +dependencies = [ + "getrandom", + "libredox", + "thiserror", +] + [[package]] name = "regex" version = "1.10.3" @@ -643,8 +1340,17 @@ checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" dependencies = [ "aho-corasick", "memchr", - "regex-automata", - "regex-syntax", + "regex-automata 0.4.5", + "regex-syntax 0.8.2", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", ] [[package]] @@ -655,9 +1361,15 @@ checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" dependencies = [ "aho-corasick", "memchr", - "regex-syntax", + "regex-syntax 0.8.2", ] +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + [[package]] name = "regex-syntax" version = "0.8.2" @@ -683,6 +1395,18 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + +[[package]] +name = "ryu" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" + [[package]] name = "schannel" version = "0.1.23" @@ -721,6 +1445,67 @@ dependencies = [ "libc", ] +[[package]] +name = "serde" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.50", +] + +[[package]] +name = "serde_json" +version = "1.0.115" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "signal-hook" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-mio" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" +dependencies = [ + "libc", + "mio", + "signal-hook", +] + [[package]] name = "signal-hook-registry" version = "1.4.1" @@ -755,6 +1540,23 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "syn" version = "2.0.50" @@ -766,6 +1568,12 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + [[package]] name = "tempfile" version = "3.10.0" @@ -778,6 +1586,21 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "textwrap" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" + [[package]] name = "thiserror" version = "1.0.57" @@ -795,9 +1618,34 @@ checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.50", ] +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "tokio" version = "1.36.0" @@ -814,9 +1662,50 @@ dependencies = [ "signal-hook-registry", "socket2", "tokio-macros", + "tracing", "windows-sys 0.48.0", ] +[[package]] +name = "tokio-console" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5ff40e8df801b383b8666967ec4aee8dc516f376d06d0e5a9f93f310763e6d2" +dependencies = [ + "atty", + "clap", + "clap_complete", + "color-eyre", + "console-api", + "crossterm", + "dirs", + "futures", + "h2", + "hdrhistogram", + "humantime", + "once_cell", + "prost-types", + "ratatui", + "regex", + "serde", + "tokio", + "toml", + "tonic", + "tower", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "tokio-io-timeout" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" +dependencies = [ + "pin-project-lite", + "tokio", +] + [[package]] name = "tokio-macros" version = "2.2.0" @@ -825,7 +1714,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.50", ] [[package]] @@ -863,12 +1752,81 @@ dependencies = [ "tracing", ] +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + +[[package]] +name = "tonic" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d560933a0de61cf715926b9cac824d4c883c2c43142f787595e48280c40a1d0e" +dependencies = [ + "async-stream", + "async-trait", + "axum", + "base64", + "bytes", + "h2", + "http", + "http-body", + "hyper", + "hyper-timeout", + "percent-encoding", + "pin-project", + "prost", + "tokio", + "tokio-stream", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "indexmap 1.9.3", + "pin-project", + "pin-project-lite", + "rand", + "slab", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + [[package]] name = "tracing" version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ + "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -882,7 +1840,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.50", ] [[package]] @@ -892,8 +1850,54 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", + "valuable", ] +[[package]] +name = "tracing-error" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e" +dependencies = [ + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + [[package]] name = "twitch-irc" version = "5.0.1" @@ -915,18 +1919,77 @@ dependencies = [ "tracing", ] +[[package]] +name = "unicode-bidi" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" + [[package]] name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[package]] +name = "unicode-normalization" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" + +[[package]] +name = "unicode-width" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" + +[[package]] +name = "url" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + [[package]] name = "vcpkg" version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -954,7 +2017,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn", + "syn 2.0.50", "wasm-bindgen-shared", ] @@ -976,7 +2039,7 @@ checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.50", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -987,6 +2050,37 @@ version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838" +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + [[package]] name = "windows-core" version = "0.52.0" diff --git a/Cargo.toml b/Cargo.toml index f3f7724..0d96343 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" [dependencies] dotenv = "0.15.0" -tokio = { version = "1.33.0", features = ["full"] } +tokio = { version = "1.33.0", features = ["full", "tracing"] } twitch-irc = "5.0.1" rand = { version = "0.8.5", features = [] } futures = "0.3" @@ -15,6 +15,8 @@ async-trait = "0.1.77" async-recursion = "1.1.0" casual_logger = "0.6.5" chrono = "0.4.35" +tokio-console = "0.1.10" +console-subscriber = "0.2.0" [lib] diff --git a/src/main.rs b/src/main.rs index 6bc6c0f..866fc38 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,6 +14,9 @@ pub type BotAR = Arc<RwLock<BotInstance>>; #[tokio::main] pub async fn main() { + console_subscriber::init(); + + Log::set_file_ext(Extension::Log); Log::set_level(Level::Trace); Log::set_retention_days(2); From 745ac915229d97e8b853a91cf4349179f0d778e5 Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Sat, 30 Mar 2024 14:26:39 -0400 Subject: [PATCH 28/33] addl debug --- src/core/bot_actions.rs | 16 +++++++++++++--- src/core/botmodules.rs | 20 +++++++++++++++++--- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/core/bot_actions.rs b/src/core/bot_actions.rs index 235637e..37f2445 100644 --- a/src/core/bot_actions.rs +++ b/src/core/bot_actions.rs @@ -56,7 +56,7 @@ impl ExecBodyParams { let curr_act = Arc::clone(&self.curr_act); let parent_act_lock = curr_act.read().await; let act = &(*parent_act_lock); - match act { + let out = match act { BotAction::C(_) => { // let temp = c.module.clone(); // Some(temp) @@ -72,10 +72,20 @@ impl ExecBodyParams { // let temp = r.module.clone(); // Some(temp) dbg!("Core > ExecBodyParams > GetChannels - routine identified"); - Some(r.read().await.channel.clone()) + dbg!(">> BotActionAR - RwLock from botmodules.rs::929:46 - current_readers = 1 "); + dbg!(">> RoutineAR - RwLock from botmodules.rs::1261:32 - current_readers = 1"); + dbg!(">> join_handle - RwLock from botmodules.rs::1226:46 - current_readers = 0"); + dbg!(">> BotInstanceAR - RwLock from botinstance.rs::150:28 - current_readers = 3 "); + // => 03.30 - Just before deadlock + let out = Some(r.read().await.channel.clone()); + + // => 03.30 - This isn't reached because of the Deadlock + dbg!(">> Just after Potential Deadlock Lock"); + out } // _ => None - } + }; + out } diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index b3c8a5f..65d902a 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -1221,9 +1221,11 @@ impl Routine { { // Recommendation to ensure a clean update is to use one write() lock that was awaited // - We can isolate the write lock by ensuring it's in it's own block - let mut lock = trg_routine_arout.write().await; + // => 03.30 - involved with Problem Deadlock Current Readers = 0 + let mut lock = trg_routine_arout.write().await; lock.join_handle = Some(Arc::new(RwLock::new(join_handle))); lock.internal_signal = RoutineSignal::Started; + drop(lock); // => 03.30 - added this to try to address Deadlock issue } trg_routine_arout.write().await.internal_signal = RoutineSignal::Started; @@ -1236,6 +1238,11 @@ impl Routine { // (routine.exec_body)(params).await; // } + + // fn (){ + + // } + async fn loopbody(&mut self) // [x] => 03.27 - COMPLETED { @@ -1248,14 +1255,18 @@ impl Routine { ); Log::flush(); - - let self_ar = Arc::new(RwLock::new(self)); + + // => 03.30 - involved with Problem Deadlock Current Readers = 1 + // - Below self appears to be a Arc<RwLock<&mut Routine>> + let self_ar = Arc::new(RwLock::new(self)); + { let mut mutlock = self_ar.write().await; mutlock.parent_params.parent_act = Some(mutlock.parent_params.curr_act.clone()); mutlock.parent_params.curr_act = mutlock.self_act_ar.to_owned().unwrap(); + drop(mutlock); // => 03.30 - Added to address Deadlock issue } dbg!("Core > Before Guards"); @@ -1275,6 +1286,9 @@ impl Routine { }; dbg!("Core > Guarding & Executing Child Execution Body"); + dbg!(">> BotActionAR - RwLock from botmodules.rs::929:46 - current_readers = 0 "); + dbg!(">> RoutineAR - RwLock from botmodules.rs::1261:32 - current_readers = Not Listed"); + dbg!(">> BotInstanceAR - RwLock from botinstance.rs::150:28 - current_readers = 3 "); { let guard2 = self_ar.read().await; From 4719b93ce553c6883ea87d4bc6478e479f1fd5c5 Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Sat, 30 Mar 2024 19:25:07 -0400 Subject: [PATCH 29/33] addl debug --- src/core/bot_actions.rs | 45 ++++++++++++++++++++---- src/core/botmodules.rs | 35 +++++++++++++++--- src/custom/experimental/experiment003.rs | 4 +-- 3 files changed, 72 insertions(+), 12 deletions(-) diff --git a/src/core/bot_actions.rs b/src/core/bot_actions.rs index 37f2445..fae3d3b 100644 --- a/src/core/bot_actions.rs +++ b/src/core/bot_actions.rs @@ -52,10 +52,33 @@ impl ExecBodyParams { pub async fn get_channel(&self) -> Option<Channel> { + dbg!("Core > ExecBodyParams > GetChannels START"); + dbg!("!! [x] Document - After SUCCESS message was sent to chat"); + dbg!(">> BotActionAR - RwLock from botmodules.rs::929:46 - current_readers = 1 "); + dbg!(">> RoutineAR - RwLock from botmodules.rs::1261:32 - current_readers = 1 "); + dbg!(">> join_handle - RwLock from botmodules.rs::1226:46 - current_readers = 0 "); + dbg!(">> BotInstanceAR - RwLock from botinstance.rs::150:28 - current_readers = 2"); + let curr_act = Arc::clone(&self.curr_act); - let parent_act_lock = curr_act.read().await; - let act = &(*parent_act_lock); + let curr_act_lock = curr_act.read().await; + + dbg!("Core > ExecBodyParams > After Creating ExecBodyParams.current_act.read() Guard "); + dbg!("!! [x] Document - After SUCCESS message was sent to chat"); + dbg!(">> BotActionAR - RwLock from botmodules.rs::929:46 - current_readers = 1 "); + dbg!(">> RoutineAR - RwLock from botmodules.rs::1261:32 - current_readers = 1 "); + dbg!(">> join_handle - RwLock from botmodules.rs::1226:46 - current_readers = 0 "); + dbg!(">> BotInstanceAR - RwLock from botinstance.rs::150:28 - current_readers = 2"); + + let act = &(*curr_act_lock); + + dbg!("Core > ExecBodyParams > Using the Read Guard "); + dbg!("!! [x] Document - After SUCCESS message was sent to chat"); + dbg!(">> BotActionAR - RwLock from botmodules.rs::929:46 - current_readers = 1 "); + dbg!(">> RoutineAR - RwLock from botmodules.rs::1261:32 - current_readers = 1"); + dbg!(">> join_handle - RwLock from botmodules.rs::1226:46 - current_readers = Not Listed "); + dbg!(">> BotInstanceAR - RwLock from botinstance.rs::150:28 - current_readers = 2"); + let out = match act { BotAction::C(_) => { // let temp = c.module.clone(); @@ -72,12 +95,22 @@ impl ExecBodyParams { // let temp = r.module.clone(); // Some(temp) dbg!("Core > ExecBodyParams > GetChannels - routine identified"); - dbg!(">> BotActionAR - RwLock from botmodules.rs::929:46 - current_readers = 1 "); - dbg!(">> RoutineAR - RwLock from botmodules.rs::1261:32 - current_readers = 1"); + dbg!("!! [x] Document"); + dbg!(">> BotActionAR - RwLock from botmodules.rs::930:46 - current_readers = 2"); + dbg!(">> RoutineAR - RwLock from botmodules.rs::1262:32 - current_readers = 1"); dbg!(">> join_handle - RwLock from botmodules.rs::1226:46 - current_readers = 0"); - dbg!(">> BotInstanceAR - RwLock from botinstance.rs::150:28 - current_readers = 3 "); + dbg!(">> BotInstanceAR - RwLock from botinstance.rs::150:28 - current_readers = 1"); // => 03.30 - Just before deadlock - let out = Some(r.read().await.channel.clone()); + // dbg!("ISSUE : RoutineAR - RwLock from botmodules.rs::1261:32 - current_readers = 1"); + // let out = Some(r.read().await.channel.clone()); + + let guard = r.read().await; + + dbg!("ISSUE> Never makes it after the read guard"); + + let channel = guard.channel.clone(); + drop(guard); + let out = Some(channel); // => 03.30 - This isn't reached because of the Deadlock dbg!(">> Just after Potential Deadlock Lock"); diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index 65d902a..5a45979 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -507,6 +507,7 @@ pub struct BotCommand { impl BotCommand { pub async fn execute(&self, params : ExecBodyParams) { + // This is how BotCommand implements their Working exec_body (*self.exec_body)(params).await; } } @@ -643,7 +644,7 @@ pub struct Routine { pub name : String , pub module : BotModule , // from() can determine this if passed parents_params pub channel : Channel , // Requiring some channel context - exec_body: bot_actions::actions_util::ExecBody, + exec_body: Arc<RwLock<bot_actions::actions_util::ExecBody>>, pub parent_params : ExecBodyParams , pub join_handle : Option<Arc<RwLock<JoinHandle<RoutineAR>>>> , start_time : Option<DateTime<Local>> , @@ -895,7 +896,7 @@ impl Routine { module : BotModule , channel : Channel, routine_attr : Vec<RoutineAttr> , - exec_body : bot_actions::actions_util::ExecBody , + exec_body : Arc<RwLock<bot_actions::actions_util::ExecBody>> , parent_params : ExecBodyParams ) -> Result< Arc<RwLock<Routine>>, @@ -1285,17 +1286,43 @@ impl Routine { parent_params }; - dbg!("Core > Guarding & Executing Child Execution Body"); + dbg!("Core > Guarding and will Execute Child Execution Body"); dbg!(">> BotActionAR - RwLock from botmodules.rs::929:46 - current_readers = 0 "); dbg!(">> RoutineAR - RwLock from botmodules.rs::1261:32 - current_readers = Not Listed"); dbg!(">> BotInstanceAR - RwLock from botinstance.rs::150:28 - current_readers = 3 "); + // { + // // The below starts the Read Lock that conlicts + // let guard2 = self_ar.read().await; + + // dbg!("Core > Guarded & Executing Child Execution Body"); + // dbg!("!! [x] Document "); + // dbg!(">> BotActionAR - RwLock from botmodules.rs::929:46 - current_readers = 0 "); + // dbg!(">> RoutineAR - RwLock from botmodules.rs::1261:32 - current_readers = 1"); + // dbg!(">> BotInstanceAR - RwLock from botinstance.rs::150:28 - current_readers = 2 "); + // // this way seems to be having issues for Routine > Loopbody + // // in particular, because by this point we have a ReadGuard on Routine + // // somehow the read guard is conflicting with a read guard in the underlying + // // fn? + // (guard2.exec_body)(parent_params).await; + // drop(guard2); + + // } + { + let guard2 = self_ar.read().await; - (guard2.exec_body)(parent_params).await; + let exec_body_ar = guard2.exec_body.clone(); drop(guard2); + let guard3 = exec_body_ar.read().await; + (guard3)(parent_params).await; + drop(guard3); + } + + + // (self_ar.read().await.exec_body)( // parent_params // ).await; diff --git a/src/custom/experimental/experiment003.rs b/src/custom/experimental/experiment003.rs index fdcdde6..0be50a3 100644 --- a/src/custom/experimental/experiment003.rs +++ b/src/custom/experimental/experiment003.rs @@ -279,7 +279,7 @@ async fn countdown_chnl_v1(params : ExecBodyParams) { module, channel.unwrap(), routine_attr, - exec_body, + Arc::new(RwLock::new(exec_body)), params.clone() ).await { let newr_ar = newr.clone(); @@ -475,7 +475,7 @@ async fn test3_body(params : ExecBodyParams) { module, channel.unwrap(), routine_attr, - exec_body, + Arc::new(RwLock::new(exec_body)), params.clone() ).await; From 000094e9c4e126ca8036abafa55d639cbc714c3e Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Sun, 31 Mar 2024 14:13:20 -0400 Subject: [PATCH 30/33] attempt blocking at getchannel failed --- src/core/bot_actions.rs | 10 ++++++++++ src/custom/experimental/experiment003.rs | 3 +++ 2 files changed, 13 insertions(+) diff --git a/src/core/bot_actions.rs b/src/core/bot_actions.rs index fae3d3b..9ad7eea 100644 --- a/src/core/bot_actions.rs +++ b/src/core/bot_actions.rs @@ -51,6 +51,7 @@ impl ExecBodyParams { } pub async fn get_channel(&self) -> Option<Channel> { + // pub fn get_channel(&self) -> Option<Channel> { dbg!("Core > ExecBodyParams > GetChannels START"); dbg!("!! [x] Document - After SUCCESS message was sent to chat"); @@ -63,6 +64,14 @@ impl ExecBodyParams { let curr_act = Arc::clone(&self.curr_act); let curr_act_lock = curr_act.read().await; + // Note : The below `curr_act.blocking_read()` is not possible. I get the following + // during runtime in this areas + /* + thread 'tokio-runtime-worker' panicked at src\core\bot_actions.rs:66:38: +Cannot block the current thread from within a runtime. This happens because a function attempted to block the current thread while the thread is being used to drive asynchronous tasks. + */ + // let curr_act_lock = curr_act.blocking_read(); + dbg!("Core > ExecBodyParams > After Creating ExecBodyParams.current_act.read() Guard "); dbg!("!! [x] Document - After SUCCESS message was sent to chat"); dbg!(">> BotActionAR - RwLock from botmodules.rs::929:46 - current_readers = 1 "); @@ -105,6 +114,7 @@ impl ExecBodyParams { // let out = Some(r.read().await.channel.clone()); let guard = r.read().await; + // let guard = r.blocking_read(); dbg!("ISSUE> Never makes it after the read guard"); diff --git a/src/custom/experimental/experiment003.rs b/src/custom/experimental/experiment003.rs index 0be50a3..774e24b 100644 --- a/src/custom/experimental/experiment003.rs +++ b/src/custom/experimental/experiment003.rs @@ -141,6 +141,7 @@ async fn countdown_chnl_v1(params : ExecBodyParams) { // let parentmodule = params.get_parent_module().await; let module = params.get_module().await; + // let channel = params.get_channel().await; let channel = params.get_channel().await; let routine_attr = vec![ // RoutineAttr::RunOnce @@ -359,6 +360,7 @@ async fn test3_body(params : ExecBodyParams) { // let parentmodule = params.get_parent_module().await; let module = params.get_module().await; + // let channel = params.get_channel().await; let channel = params.get_channel().await; let routine_attr = vec![ RoutineAttr::RunOnce @@ -436,6 +438,7 @@ async fn test3_body(params : ExecBodyParams) { // BotAction::C(_) | BotAction::L(_) => None , // } ; + // let chnl = params.get_channel().await; let chnl = params.get_channel().await; dbg!("Custom > within Child Custom fn - after GetChannel"); println!("{:?}",chnl); From fa5de03bae027336c17373dd463832264b22206d Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Sun, 31 Mar 2024 16:38:11 -0400 Subject: [PATCH 31/33] used blocking instead of async in some calls --- src/core/bot_actions.rs | 17 +++-- src/core/botmodules.rs | 93 +++++++++++++++++------- src/custom/experimental/experiment003.rs | 90 ++++++++++++++++------- src/main.rs | 9 ++- 4 files changed, 147 insertions(+), 62 deletions(-) diff --git a/src/core/bot_actions.rs b/src/core/bot_actions.rs index 9ad7eea..7775beb 100644 --- a/src/core/bot_actions.rs +++ b/src/core/bot_actions.rs @@ -50,8 +50,8 @@ impl ExecBodyParams { } } - pub async fn get_channel(&self) -> Option<Channel> { - // pub fn get_channel(&self) -> Option<Channel> { + // pub async fn get_channel(&self) -> Option<Channel> { + pub fn get_channel(&self) -> Option<Channel> { dbg!("Core > ExecBodyParams > GetChannels START"); dbg!("!! [x] Document - After SUCCESS message was sent to chat"); @@ -62,7 +62,7 @@ impl ExecBodyParams { let curr_act = Arc::clone(&self.curr_act); - let curr_act_lock = curr_act.read().await; + // let curr_act_lock = curr_act.read().await; // Note : The below `curr_act.blocking_read()` is not possible. I get the following // during runtime in this areas @@ -70,7 +70,7 @@ impl ExecBodyParams { thread 'tokio-runtime-worker' panicked at src\core\bot_actions.rs:66:38: Cannot block the current thread from within a runtime. This happens because a function attempted to block the current thread while the thread is being used to drive asynchronous tasks. */ - // let curr_act_lock = curr_act.blocking_read(); + let curr_act_lock = curr_act.blocking_read(); dbg!("Core > ExecBodyParams > After Creating ExecBodyParams.current_act.read() Guard "); dbg!("!! [x] Document - After SUCCESS message was sent to chat"); @@ -113,10 +113,13 @@ Cannot block the current thread from within a runtime. This happens because a fu // dbg!("ISSUE : RoutineAR - RwLock from botmodules.rs::1261:32 - current_readers = 1"); // let out = Some(r.read().await.channel.clone()); - let guard = r.read().await; - // let guard = r.blocking_read(); + + dbg!("ISSUE > Never makes it after the following read guard"); - dbg!("ISSUE> Never makes it after the read guard"); + // let guard = r.read().await; + let guard = r.blocking_read(); + + dbg!("ISSUE RESOLVED > If passed htis point"); let channel = guard.channel.clone(); drop(guard); diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index 5a45979..5bc9f0a 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -644,8 +644,11 @@ pub struct Routine { pub name : String , pub module : BotModule , // from() can determine this if passed parents_params pub channel : Channel , // Requiring some channel context - exec_body: Arc<RwLock<bot_actions::actions_util::ExecBody>>, - pub parent_params : ExecBodyParams , + // exec_body: Arc<RwLock<bot_actions::actions_util::ExecBody>>, + // exec_body : fn(ExecBodyParams), + exec_body : fn(Arc<RwLock<ExecBodyParams>>), + // pub parent_params : ExecBodyParams , + pub parent_params : Arc<RwLock<ExecBodyParams>> , pub join_handle : Option<Arc<RwLock<JoinHandle<RoutineAR>>>> , start_time : Option<DateTime<Local>> , pub complete_iterations : i64 , @@ -896,8 +899,9 @@ impl Routine { module : BotModule , channel : Channel, routine_attr : Vec<RoutineAttr> , - exec_body : Arc<RwLock<bot_actions::actions_util::ExecBody>> , - parent_params : ExecBodyParams + // exec_body : Arc<RwLock<bot_actions::actions_util::ExecBody>> , + exec_body : fn(Arc<RwLock<ExecBodyParams>>) , + parent_params : Arc<RwLock<ExecBodyParams>> ) -> Result< Arc<RwLock<Routine>>, String @@ -1014,7 +1018,7 @@ impl Routine { Some(format!( "Routine > start() > (In Tokio Spawn)", )), - Some(&trg_routine_ar.read().await.parent_params.msg), + Some(&trg_routine_ar.read().await.parent_params.read().await.msg), ); Log::flush(); @@ -1027,7 +1031,7 @@ impl Routine { Some(format!( "Routine > start() > (In Tokio Spawn)", )), - Some(&trg_routine_ar.read().await.parent_params.msg), + Some(&trg_routine_ar.read().await.parent_params.read().await.msg), ); Log::flush(); @@ -1110,7 +1114,7 @@ impl Routine { "Routine > start() > (In Tokio Spawn) > {:?}", trg_routine_ar.read().await.module )), - Some(&trg_routine_ar.read().await.parent_params.msg), + Some(&trg_routine_ar.read().await.parent_params.read().await.msg), ); if let Some(dur) = delayduration { @@ -1119,6 +1123,8 @@ impl Routine { { // [x] Loop Initialization - Prior to Loop that calls Custom Routine Execution Body + + let mut a = trg_routine_ar.write().await; a.start_time = Some(chrono::offset::Local::now()); @@ -1129,15 +1135,33 @@ impl Routine { { a.remaining_iterations = Some(iternum); } + drop(a); } + loop { // [x] Routine loop // [x] execution body // trg_routine_ar.read().await.loopbody().await; { - trg_routine_ar.write().await.loopbody().await; + + let trg_routine_ar_clone = trg_routine_ar.clone(); + // trg_routine_ar.write().await.loopbody().await; + let loopbodyspawn = tokio::task::spawn_blocking( move || { + // let routine_ar_clone = Arc::clone(&trg_routine_ar); + // trg_routine_ar + // trg_routine_ar_clone.blocking_write().loopbody(); + let guard1 = trg_routine_ar_clone.blocking_read(); + guard1.loopbody(); + drop(guard1); + }); + + loopbodyspawn.await.unwrap(); + + + // trg_routine_ar.write().await.loopbody() + } @@ -1156,6 +1180,7 @@ impl Routine { if i > 0 { a.remaining_iterations = Some(i-1) ; } else { break ; } // if remaining iterations is 0, exit } + drop(a); } @@ -1184,6 +1209,8 @@ impl Routine { } + dbg!("SUCCESS! Routinecompleted"); + botlog::trace( format!( @@ -1196,7 +1223,7 @@ impl Routine { "Routine > start() > (In Tokio Spawn) > {:?}", trg_routine_ar.read().await.module )), - Some(&trg_routine_ar.read().await.parent_params.msg), + Some(&trg_routine_ar.read().await.parent_params.read().await.msg), ); botlog::trace( @@ -1211,7 +1238,7 @@ impl Routine { "Routine > start() > (In Tokio Spawn) > {:?}", trg_routine_ar.read().await.module )), - Some(&trg_routine_ar.read().await.parent_params.msg), + Some(&trg_routine_ar.read().await.parent_params.read().await.msg), ); Log::flush(); @@ -1229,7 +1256,7 @@ impl Routine { drop(lock); // => 03.30 - added this to try to address Deadlock issue } - trg_routine_arout.write().await.internal_signal = RoutineSignal::Started; + // trg_routine_arout.write().await.internal_signal = RoutineSignal::Started; return Ok(trg_routine_arout); @@ -1244,7 +1271,9 @@ impl Routine { // } - async fn loopbody(&mut self) + // async fn loopbody(&mut self) + // fn loopbody(&mut self) + fn loopbody(&self) // [x] => 03.27 - COMPLETED { botlog::trace( @@ -1260,15 +1289,19 @@ impl Routine { // => 03.30 - involved with Problem Deadlock Current Readers = 1 // - Below self appears to be a Arc<RwLock<&mut Routine>> let self_ar = Arc::new(RwLock::new(self)); - + + // => 03.31 - Temporarily removing the current_act / parrent_act functionality + /* { - let mut mutlock = self_ar.write().await; + // let mutlock = self_ar.read().await; + let mutlock = self_ar.blocking_read(); - mutlock.parent_params.parent_act = Some(mutlock.parent_params.curr_act.clone()); - mutlock.parent_params.curr_act = mutlock.self_act_ar.to_owned().unwrap(); + mutlock.parent_params.blocking_write().parent_act = Some(mutlock.parent_params.blocking_read().curr_act.clone()); + mutlock.parent_params.blocking_write().curr_act = mutlock.self_act_ar.to_owned().unwrap(); drop(mutlock); // => 03.30 - Added to address Deadlock issue } + */ dbg!("Core > Before Guards"); @@ -1279,7 +1312,7 @@ impl Routine { // ).await; let parent_params = { - let guard1 = self_ar.read().await; + let guard1 = self_ar.blocking_read(); let parent_params = guard1.parent_params.clone(); drop(guard1); @@ -1311,12 +1344,15 @@ impl Routine { { - let guard2 = self_ar.read().await; + let guard2 = self_ar.blocking_read(); let exec_body_ar = guard2.exec_body.clone(); drop(guard2); - let guard3 = exec_body_ar.read().await; - (guard3)(parent_params).await; - drop(guard3); + // let guard3 = exec_body_ar.read().await; + // (guard3)(parent_params).await; + // drop(guard3); + + // [ ] May need to do a blocking async of this? + exec_body_ar(parent_params); } @@ -1343,6 +1379,7 @@ impl Routine { { let mut self_lock = self_rw.write().await; self_lock.internal_signal = RoutineSignal::Stopping; + drop(self_lock); } @@ -1358,7 +1395,7 @@ impl Routine { "Routine > stop() > {:?}", self_lock.module )), - Some(&self_lock.parent_params.msg), + Some(&self_lock.parent_params.read().await.msg), ); Log::flush(); @@ -1403,6 +1440,7 @@ impl Routine { { let mut lock_mut = self_rw.write().await; lock_mut.internal_signal = RoutineSignal::Stopped; + drop(lock_mut); } } @@ -1419,7 +1457,7 @@ impl Routine { "Routine > cancel() > {:?}", self_lock.module )), - Some(&self_lock.parent_params.msg), + Some(&self_lock.parent_params.read().await.msg), ); Log::flush(); @@ -1459,9 +1497,11 @@ impl Routine { { let mut self_lock = self_rw.write().await; self_lock.cancel().await?; + drop(self_lock); } else { let mut self_lock = self_rw.write().await; self_lock.stop().await?; + drop(self_lock); } Routine::start(self_rw.clone()).await?; @@ -1478,7 +1518,7 @@ impl Routine { "Routine > restart() > {:?}", self_lock.module )), - Some(&self_lock.parent_params.msg), + Some(&self_lock.parent_params.read().await.msg), ); Log::flush(); @@ -1512,7 +1552,7 @@ impl Routine { "Routine > restart() > {:?}", self_lock.module )), - Some(&self_lock.parent_params.msg), + Some(&self_lock.parent_params.read().await.msg), ); Log::flush(); @@ -1539,6 +1579,7 @@ impl Routine { { let mut self_lock = self_rw.write().await; self_lock.routine_attr = routine_attr; + drop(self_lock); } // let self_rw = Arc::new(RwLock::new(self)); @@ -1555,7 +1596,7 @@ impl Routine { "Routine > restart() > {:?}", self_lock.module )), - Some(&self_lock.parent_params.msg), + Some(&self_lock.parent_params.read().await.msg), ); Log::flush(); diff --git a/src/custom/experimental/experiment003.rs b/src/custom/experimental/experiment003.rs index 774e24b..6b5a3de 100644 --- a/src/custom/experimental/experiment003.rs +++ b/src/custom/experimental/experiment003.rs @@ -142,19 +142,24 @@ async fn countdown_chnl_v1(params : ExecBodyParams) { // let parentmodule = params.get_parent_module().await; let module = params.get_module().await; // let channel = params.get_channel().await; - let channel = params.get_channel().await; + // let channel = params.get_channel().await; + let channel = params.get_channel(); let routine_attr = vec![ // RoutineAttr::RunOnce RoutineAttr::MaxIterations(5), RoutineAttr::LoopDuration(Duration::from_secs(1)) ]; // let exec_body = actions_util::asyncbox(rtestbody); - let exec_body = actions_util::asyncbox(innertester); // <-- 03.27 - when below is uncommented, this is throwing an issue + // let exec_body = actions_util::asyncbox(innertester); // <-- 03.27 - when below is uncommented, this is throwing an issue + let exec_body = innertester; - async fn innertester(params : ExecBodyParams) { + // async fn innertester(params : ExecBodyParams) { + fn innertester(params : Arc<RwLock<ExecBodyParams>>) { { - let curract_guard = params.curr_act.read().await; + // let curract_guard = params.curr_act.read().await; + let paramguard1 = params.blocking_read(); + let curract_guard = paramguard1.curr_act.blocking_read(); // let logmsg_botact = match *params.curr_act.read().await { @@ -169,16 +174,19 @@ async fn countdown_chnl_v1(params : ExecBodyParams) { botlog::trace( format!("Params > Curr_act type : {:?}", logmsg_botact).as_str(), Some("Experiments003 > countdown_chnl()".to_string()), - Some(¶ms.msg), + Some(¶ms.blocking_read().msg), ); Log::flush(); } { - let bot = Arc::clone(¶ms.bot); - let botlock = bot.read().await; + let bot = Arc::clone(¶ms.blocking_read().bot); + // let botlock = bot.read().await; + let botlock = bot.blocking_read(); - let curract_guard = params.curr_act.write().await; + // let curract_guard = params.curr_act.write().await; + let paramguard1 = params.blocking_read(); + let curract_guard = paramguard1.curr_act.blocking_write(); // let routine_lock = arr.write().await; @@ -208,7 +216,8 @@ async fn countdown_chnl_v1(params : ExecBodyParams) { // } { - let routine_lock = arr.write().await; + // let routine_lock = arr.write().await; + let routine_lock = arr.blocking_write(); let a = routine_lock.remaining_iterations; println!("remaining iterations : {:?}", a); } @@ -248,7 +257,7 @@ async fn countdown_chnl_v1(params : ExecBodyParams) { botlog::trace( format!("Picked a channel: {:?}", chosen_channel).as_str(), Some("Experiments003 > countdown_chnl()".to_string()), - Some(¶ms.msg), + Some(¶ms.blocking_read().msg), ); Log::flush(); @@ -280,8 +289,9 @@ async fn countdown_chnl_v1(params : ExecBodyParams) { module, channel.unwrap(), routine_attr, - Arc::new(RwLock::new(exec_body)), - params.clone() + // Arc::new(RwLock::new(exec_body)), + exec_body, + Arc::new(RwLock::new(params.clone())), ).await { let newr_ar = newr.clone(); // [ ] start the routine @@ -358,25 +368,47 @@ async fn test3_body(params : ExecBodyParams) { // [x] Get the module from params + + let params_ar = Arc::new(RwLock::new(params)); + // let parentmodule = params.get_parent_module().await; - let module = params.get_module().await; + let module = params_ar.read().await.get_module().await; // let channel = params.get_channel().await; - let channel = params.get_channel().await; + // let channel = params.get_channel().await; + // let channel = params.get_channel(); let routine_attr = vec![ RoutineAttr::RunOnce ]; // let exec_body = actions_util::asyncbox(rtestbody); - let exec_body = actions_util::asyncbox(rtestbody); // <-- 03.27 - when below is uncommented, this is throwing an issue + // let exec_body = actions_util::asyncbox(rtestbody); // <-- 03.27 - when below is uncommented, this is throwing an issue + // let channel = params.get_channel(); + let channel_task_grabber = tokio::task::spawn_blocking( move || { + let params_clone = params_ar.clone(); + let channel = params_clone.blocking_read().get_channel(); + drop(params_clone); + (channel,params_ar) + }); + + let (channel,params_ar) = channel_task_grabber.await.unwrap(); + + + + + + let exec_body = rtestbody; // let parent_params = params.clone(); // let params_clone = params.clone(); - async fn rtestbody(params : ExecBodyParams) { + // async fn rtestbody(params : ExecBodyParams) { + fn rtestbody(params : Arc<RwLock<ExecBodyParams>>) { - let guard1 = params.curr_act.read().await; + // let guard1 = params.curr_act.read().await; + let paramguard1 = params.blocking_read(); + let guard1 = paramguard1.curr_act.blocking_read(); { let logmsg_botact = match *guard1 { BotAction::C(_) => "command", @@ -387,7 +419,7 @@ async fn test3_body(params : ExecBodyParams) { botlog::trace( format!("Params > Curr_act type : {:?}", logmsg_botact).as_str(), Some("Experiments003 > test3 command body".to_string()), - Some(¶ms.msg), + Some(¶ms.blocking_read().msg), ); Log::flush(); } @@ -403,7 +435,7 @@ async fn test3_body(params : ExecBodyParams) { botlog::trace( format!("Params > Curr_act type : {:?}", logmsg_botact).as_str(), Some("Experiments003 > test3 command body".to_string()), - Some(¶ms.msg), + Some(¶ms.blocking_read().msg), ); Log::flush(); } @@ -439,7 +471,8 @@ async fn test3_body(params : ExecBodyParams) { // } ; // let chnl = params.get_channel().await; - let chnl = params.get_channel().await; + // let chnl = params.get_channel().await; + let chnl = params.blocking_read().get_channel(); dbg!("Custom > within Child Custom fn - after GetChannel"); println!("{:?}",chnl); @@ -461,14 +494,14 @@ async fn test3_body(params : ExecBodyParams) { } - + let params_clone = params_ar.clone(); botlog::debug( format!("RTESTBODY : module - {:?} ; channel - {:?}", module,channel ).as_str(), Some("experiment003 > test3_body".to_string()), - Some(¶ms.msg), + Some(¶ms_clone.read().await.msg), ); @@ -478,8 +511,9 @@ async fn test3_body(params : ExecBodyParams) { module, channel.unwrap(), routine_attr, - Arc::new(RwLock::new(exec_body)), - params.clone() + // Arc::new(RwLock::new(exec_body)), + exec_body, + Arc::new(RwLock::new(params_clone.read().await.clone())) ).await; @@ -520,12 +554,12 @@ async fn test3_body(params : ExecBodyParams) { rsltstr ).as_str(), Some("experiment003 > test3_body".to_string()), - Some(¶ms.msg), + Some(&(params_ar.clone()).read().await.msg), ); Log::flush(); - let bot = Arc::clone(¶ms.bot); + let bot = Arc::clone(¶ms_ar.read().await.bot); let botlock = bot.read().await; @@ -534,9 +568,9 @@ async fn test3_body(params : ExecBodyParams) { .botmgrs .chat .say_in_reply_to( - ¶ms.msg, + ¶ms_ar.read().await.msg, format!("Routine Result : {:?}",rsltstr), - params.clone() + params_clone.read().await.clone() ).await; // [x] Will not be handling JoinHandles here . If immediate abort() handling is required, below is an example that works diff --git a/src/main.rs b/src/main.rs index 866fc38..3a797a4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -22,7 +22,14 @@ pub async fn main() { Log::set_retention_days(2); // Log::set_level(Level::Notice); - + // fn innerbody() -> i64 { + // println!("hello"); + // 64 + // } + + // let exec_body:fn() -> i64 = innerbody; + + From e711c6454dd29456103d9e3ec6a3c2707cc5691f Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Sun, 31 Mar 2024 20:09:00 -0400 Subject: [PATCH 32/33] ExecBodyParams curr_act --- src/core/bot_actions.rs | 14 +++-- src/core/botinstance.rs | 10 ++-- src/core/botmodules.rs | 65 ++++++++++++++++------ src/custom/experimental/experiment003.rs | 70 +++++++++++++++++------- 4 files changed, 112 insertions(+), 47 deletions(-) diff --git a/src/core/bot_actions.rs b/src/core/bot_actions.rs index 7775beb..4a07d9e 100644 --- a/src/core/bot_actions.rs +++ b/src/core/bot_actions.rs @@ -17,7 +17,13 @@ pub struct ExecBodyParams { pub bot : BotAR, pub msg : PrivmsgMessage, pub parent_act : Option<ActAR> , - pub curr_act : ActAR , + pub curr_act : Option<ActAR> , +} + +#[derive(Debug,Eq,PartialEq,Hash)] +pub enum ParamLevel { + Parent, + Current, } @@ -27,8 +33,8 @@ impl ExecBodyParams { // pub async fn get_parent_module(&self) -> BotModule { pub async fn get_module(&self) -> BotModule { - let curr_act = Arc::clone(&self.curr_act); - let parent_act_lock = curr_act.read().await; + let curr_acta = Arc::clone(&(self.curr_act.clone().unwrap())); + let parent_act_lock = curr_acta.read().await; let act = &(*parent_act_lock); match act { BotAction::C(c) => { @@ -61,7 +67,7 @@ impl ExecBodyParams { dbg!(">> BotInstanceAR - RwLock from botinstance.rs::150:28 - current_readers = 2"); - let curr_act = Arc::clone(&self.curr_act); + let curr_act = Arc::clone(&self.curr_act.clone().unwrap()); // let curr_act_lock = curr_act.read().await; // Note : The below `curr_act.blocking_read()` is not possible. I get the following diff --git a/src/core/botinstance.rs b/src/core/botinstance.rs index 2c06cea..d17f8c8 100644 --- a/src/core/botinstance.rs +++ b/src/core/botinstance.rs @@ -406,7 +406,7 @@ impl BotInstance { bot : Arc::clone(&bot), msg : (*msg).clone(), parent_act : None, - curr_act : Arc::clone(&act_clone), + curr_act : Some(Arc::clone(&act_clone)), }; // When sending a BotMsgTypeNotif, send_botmsg does Roles related validation as required @@ -464,7 +464,7 @@ impl BotInstance { bot : Arc::clone(&bot), msg : (*msg).clone(), parent_act : None, - curr_act : Arc::clone(&act_clone), + curr_act : Some(Arc::clone(&act_clone)), }; @@ -495,7 +495,7 @@ impl BotInstance { bot : Arc::clone(&bot), msg : (*msg).clone(), parent_act : None, - curr_act : Arc::clone(&act_clone), + curr_act : Some(Arc::clone(&act_clone)), }; @@ -521,7 +521,7 @@ impl BotInstance { bot : a, msg : msg.clone() , parent_act : None, - curr_act : Arc::clone(&act_clone), + curr_act : Some(Arc::clone(&act_clone)), }).await; botlog::trace( @@ -570,7 +570,7 @@ impl BotInstance { bot : a, msg : msg.clone() , parent_act : None, - curr_act : Arc::clone(&act_clone), + curr_act : Some(Arc::clone(&act_clone)), } ).await; } diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index 5bc9f0a..fcc731e 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -57,6 +57,7 @@ use crate::core::bot_actions; use std::hash::{Hash, Hasher}; use super::bot_actions::ActAR; +use super::bot_actions::ParamLevel; use super::bot_actions::RoutineAR; use super::identity::ChatBadge; @@ -640,15 +641,18 @@ pub enum RoutineSignal { NotStarted, } +pub type ExecBodyParamsAr = Arc<RwLock<ExecBodyParams>>; + pub struct Routine { pub name : String , pub module : BotModule , // from() can determine this if passed parents_params pub channel : Channel , // Requiring some channel context // exec_body: Arc<RwLock<bot_actions::actions_util::ExecBody>>, // exec_body : fn(ExecBodyParams), - exec_body : fn(Arc<RwLock<ExecBodyParams>>), + exec_body : fn(ExecBodyParamsAr), // pub parent_params : ExecBodyParams , - pub parent_params : Arc<RwLock<ExecBodyParams>> , + // pub parent_params : Arc<RwLock<ExecBodyParams>> , + pub params : HashMap<ParamLevel,ExecBodyParamsAr>, pub join_handle : Option<Arc<RwLock<JoinHandle<RoutineAR>>>> , start_time : Option<DateTime<Local>> , pub complete_iterations : i64 , @@ -665,7 +669,7 @@ impl Debug for Routine { write!(f, "{:?}", self.name)?; write!(f, "{:?}", self.module)?; write!(f, "{:?}", self.channel)?; - write!(f, "{:?}", self.parent_params)?; + write!(f, "{:?}", self.params)?; write!(f, "{:?}", self.join_handle)?; write!(f, "{:?}", self.start_time)?; write!(f, "{:?}", self.complete_iterations)?; @@ -911,12 +915,27 @@ impl Routine { Routine::validate_attr(&routine_attr).await?; + let mut params = HashMap::new(); + params.insert(ParamLevel::Parent,parent_params.clone()); + + let pparam_clone = parent_params.clone(); + let parent_guard = pparam_clone.read().await; + let curr_params = ExecBodyParams { + bot : parent_guard.bot.clone(), + msg : parent_guard.msg.clone(), + parent_act : parent_guard.curr_act.clone() , + curr_act : None, + }; + + params.insert(ParamLevel::Current,Arc::new(RwLock::new(curr_params))); + let routine_ar = Arc::new(RwLock::new(Routine { name , module , channel , exec_body , - parent_params , + // parent_params , + params, join_handle : None , start_time : None , complete_iterations : 0 , @@ -933,6 +952,8 @@ impl Routine { // 2. Update the current self_act_ar mut_lock.self_act_ar = Some(Arc::new(RwLock::new(BotAction::R(routine_ar.clone())))); + mut_lock.params.get(&ParamLevel::Current).unwrap().write().await.curr_act = Some(Arc::new(RwLock::new(BotAction::R(routine_ar.clone())))); + Ok(routine_ar.clone()) // return Ok(Arc::new(RwLock::new(Routine { @@ -1018,7 +1039,7 @@ impl Routine { Some(format!( "Routine > start() > (In Tokio Spawn)", )), - Some(&trg_routine_ar.read().await.parent_params.read().await.msg), + Some(&trg_routine_ar.read().await.params.get(&ParamLevel::Parent).unwrap().read().await.msg), ); Log::flush(); @@ -1031,7 +1052,7 @@ impl Routine { Some(format!( "Routine > start() > (In Tokio Spawn)", )), - Some(&trg_routine_ar.read().await.parent_params.read().await.msg), + Some(&trg_routine_ar.read().await.params.get(&ParamLevel::Parent).unwrap().read().await.msg), ); Log::flush(); @@ -1114,7 +1135,7 @@ impl Routine { "Routine > start() > (In Tokio Spawn) > {:?}", trg_routine_ar.read().await.module )), - Some(&trg_routine_ar.read().await.parent_params.read().await.msg), + Some(&trg_routine_ar.read().await.params.get(&ParamLevel::Parent).unwrap().read().await.msg), ); if let Some(dur) = delayduration { @@ -1223,7 +1244,7 @@ impl Routine { "Routine > start() > (In Tokio Spawn) > {:?}", trg_routine_ar.read().await.module )), - Some(&trg_routine_ar.read().await.parent_params.read().await.msg), + Some(&trg_routine_ar.read().await.params.get(&ParamLevel::Parent).unwrap().read().await.msg), ); botlog::trace( @@ -1238,7 +1259,7 @@ impl Routine { "Routine > start() > (In Tokio Spawn) > {:?}", trg_routine_ar.read().await.module )), - Some(&trg_routine_ar.read().await.parent_params.read().await.msg), + Some(&trg_routine_ar.read().await.params.get(&ParamLevel::Parent).unwrap().read().await.msg), ); Log::flush(); @@ -1311,14 +1332,22 @@ impl Routine { // self_ar.read().await.parent_params.clone() // ).await; - let parent_params = { + // let parent_params = { + // let guard1 = self_ar.blocking_read(); + + // let parent_params = guard1.params.get(&ParamLevel::Parent).unwrap().clone(); + // drop(guard1); + // parent_params + // }; + let curr_params = { let guard1 = self_ar.blocking_read(); - let parent_params = guard1.parent_params.clone(); + let curr_params = guard1.params.get(&ParamLevel::Current).unwrap().clone(); drop(guard1); - parent_params + curr_params }; + dbg!("Core > Guarding and will Execute Child Execution Body"); dbg!(">> BotActionAR - RwLock from botmodules.rs::929:46 - current_readers = 0 "); dbg!(">> RoutineAR - RwLock from botmodules.rs::1261:32 - current_readers = Not Listed"); @@ -1352,7 +1381,7 @@ impl Routine { // drop(guard3); // [ ] May need to do a blocking async of this? - exec_body_ar(parent_params); + exec_body_ar(curr_params); } @@ -1395,7 +1424,7 @@ impl Routine { "Routine > stop() > {:?}", self_lock.module )), - Some(&self_lock.parent_params.read().await.msg), + Some(&self_lock.params.get(&ParamLevel::Parent).unwrap().read().await.msg), ); Log::flush(); @@ -1457,7 +1486,7 @@ impl Routine { "Routine > cancel() > {:?}", self_lock.module )), - Some(&self_lock.parent_params.read().await.msg), + Some(&self_lock.params.get(&ParamLevel::Parent).unwrap().read().await.msg), ); Log::flush(); @@ -1518,7 +1547,7 @@ impl Routine { "Routine > restart() > {:?}", self_lock.module )), - Some(&self_lock.parent_params.read().await.msg), + Some(&self_lock.params.get(&ParamLevel::Parent).unwrap().read().await.msg), ); Log::flush(); @@ -1552,7 +1581,7 @@ impl Routine { "Routine > restart() > {:?}", self_lock.module )), - Some(&self_lock.parent_params.read().await.msg), + Some(&self_lock.params.get(&ParamLevel::Parent).unwrap().read().await.msg), ); Log::flush(); @@ -1596,7 +1625,7 @@ impl Routine { "Routine > restart() > {:?}", self_lock.module )), - Some(&self_lock.parent_params.read().await.msg), + Some(&self_lock.params.get(&ParamLevel::Parent).unwrap().read().await.msg), ); Log::flush(); diff --git a/src/custom/experimental/experiment003.rs b/src/custom/experimental/experiment003.rs index 6b5a3de..45e637b 100644 --- a/src/custom/experimental/experiment003.rs +++ b/src/custom/experimental/experiment003.rs @@ -139,11 +139,23 @@ async fn countdown_chnl_v1(params : ExecBodyParams) { // [ ] 1. Create a Routine & start a routine + let params_ar = Arc::new(RwLock::new(params)); + // let parentmodule = params.get_parent_module().await; - let module = params.get_module().await; + let module = params_ar.read().await.get_module().await; // let channel = params.get_channel().await; // let channel = params.get_channel().await; - let channel = params.get_channel(); + // let channel = params.get_channel(); + + let channel_task_grabber = tokio::task::spawn_blocking( move || { + let params_clone = params_ar.clone(); + let channel = params_clone.blocking_read().get_channel(); + drop(params_clone); + (channel,params_ar) + }); + + let (channel,params_ar) = channel_task_grabber.await.unwrap(); + let routine_attr = vec![ // RoutineAttr::RunOnce RoutineAttr::MaxIterations(5), @@ -159,7 +171,8 @@ async fn countdown_chnl_v1(params : ExecBodyParams) { { // let curract_guard = params.curr_act.read().await; let paramguard1 = params.blocking_read(); - let curract_guard = paramguard1.curr_act.blocking_read(); + let curract = paramguard1.curr_act.clone().unwrap(); + let curract_guard = curract.blocking_read(); // let logmsg_botact = match *params.curr_act.read().await { @@ -186,7 +199,8 @@ async fn countdown_chnl_v1(params : ExecBodyParams) { // let curract_guard = params.curr_act.write().await; let paramguard1 = params.blocking_read(); - let curract_guard = paramguard1.curr_act.blocking_write(); + let curract = paramguard1.curr_act.clone().unwrap(); + let curract_guard = curract.blocking_write(); // let routine_lock = arr.write().await; @@ -215,11 +229,13 @@ async fn countdown_chnl_v1(params : ExecBodyParams) { // println!("Remaining iterations > {}",a) // } + let iterleft; { // let routine_lock = arr.write().await; - let routine_lock = arr.blocking_write(); - let a = routine_lock.remaining_iterations; - println!("remaining iterations : {:?}", a); + // let routine_lock = arr.blocking_write(); + let routine_lock = arr.blocking_read(); + iterleft = routine_lock.remaining_iterations.unwrap_or(0); + println!("remaining iterations : {:?}", iterleft); } botlog::trace( @@ -254,26 +270,39 @@ async fn countdown_chnl_v1(params : ExecBodyParams) { let chosen_channel = pick_a_channel(joinedchannels); + dbg!("SUCCESS", chosen_channel.clone()); + botlog::trace( format!("Picked a channel: {:?}", chosen_channel).as_str(), Some("Experiments003 > countdown_chnl()".to_string()), Some(¶ms.blocking_read().msg), ); Log::flush(); + + // let a = || { - // let outmsg = if iterleft == 1 { + // let chosen_channel_ar = Arc::new(RwLock::new(chosen_channel)); + + // let params_clone = params.clone(); + // let bot = Arc::clone(¶ms.blocking_read().bot); + + + // dbg!("in chat async function"); + + // let botlock = bot.blocking_read(); + // let channel_ar_clone = chosen_channel_ar.clone(); + + // let outmsg = if iterleft <= 1 { // format!("{} I love you uwu~",iterleft) // } else { format!("{}",iterleft) }; // botlock.botmgrs.chat // .say( - // // joinedchannels.choose(&mut rng).unwrap().0.clone(), - // chosen_channel.0.clone(), + // channel_ar_clone.read().await.0.clone(), // outmsg, - // params.clone() - - - // ).await; + // params_clone.read().await.clone() + // ).await; + } } @@ -291,7 +320,7 @@ async fn countdown_chnl_v1(params : ExecBodyParams) { routine_attr, // Arc::new(RwLock::new(exec_body)), exec_body, - Arc::new(RwLock::new(params.clone())), + Arc::new(RwLock::new(params_ar.clone().read().await.clone())), ).await { let newr_ar = newr.clone(); // [ ] start the routine @@ -301,13 +330,13 @@ async fn countdown_chnl_v1(params : ExecBodyParams) { botlog::debug( "Successfully started", Some("experiment003 > countdown_chnl()".to_string()), - Some(¶ms.msg), + Some(¶ms_ar.read().await.msg), ); Log::flush(); - let bot = Arc::clone(¶ms.bot); + let bot = Arc::clone(¶ms_ar.read().await.bot); let botlock = bot.read().await; @@ -316,9 +345,9 @@ async fn countdown_chnl_v1(params : ExecBodyParams) { .botmgrs .chat .say_in_reply_to( - ¶ms.msg, + ¶ms_ar.read().await.msg, "Started Routine!".to_string(), - params.clone() + params_ar.read().await.clone() ).await; // let jhandle = newr.clone().read().await.join_handle.clone().unwrap(); @@ -408,7 +437,8 @@ async fn test3_body(params : ExecBodyParams) { // let guard1 = params.curr_act.read().await; let paramguard1 = params.blocking_read(); - let guard1 = paramguard1.curr_act.blocking_read(); + let curract = paramguard1.curr_act.clone().unwrap(); + let guard1 = curract.blocking_read(); { let logmsg_botact = match *guard1 { BotAction::C(_) => "command", From 8ed672fb3a3e452d5f0299bc44dec11a8cfe351d Mon Sep 17 00:00:00 2001 From: ModulatingForce <116608425+modulatingforce@users.noreply.github.com> Date: Sun, 31 Mar 2024 20:12:49 -0400 Subject: [PATCH 33/33] comment issue with fix --- src/custom/experimental/experiment003.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/custom/experimental/experiment003.rs b/src/custom/experimental/experiment003.rs index 45e637b..ed1c6ba 100644 --- a/src/custom/experimental/experiment003.rs +++ b/src/custom/experimental/experiment003.rs @@ -279,6 +279,11 @@ async fn countdown_chnl_v1(params : ExecBodyParams) { ); Log::flush(); + // [ ] !! ISSUE : With this fix though, the custom fn is no longer + // async. This is an issue because chat module is async + // - There should be no need to change chat , as async allows + // us to multitask with messages + // let a = || { // let chosen_channel_ar = Arc::new(RwLock::new(chosen_channel));