WIP: Basic Routine Functionality #40

Draft
modulatingforce wants to merge 23 commits from routines-functionality into master
Showing only changes of commit 2ba92388a2 - Show all commits

View file

@ -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())