impl stop

This commit is contained in:
ModulatingForce 2024-03-28 02:13:38 -04:00
parent 6c3a151668
commit 4637312da9

View file

@ -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)] // #[derive(Debug)]
pub struct Routine { pub struct Routine {
pub name : String , pub name : String ,
@ -627,6 +635,7 @@ pub struct Routine {
pub complete_iterations : i64 , pub complete_iterations : i64 ,
remaining_iterations : Option<i64> , remaining_iterations : Option<i64> ,
routine_attr : Vec<RoutineAttr> , routine_attr : Vec<RoutineAttr> ,
pub internal_signal : RoutineSignal ,
} }
@ -807,25 +816,13 @@ impl Routine {
start_time : None , start_time : None ,
complete_iterations : 0 , complete_iterations : 0 ,
remaining_iterations : None , 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( pub async fn start(
trg_routine_ar : Arc<RwLock<Routine>> trg_routine_ar : Arc<RwLock<Routine>>
// ) -> Result<String,String> // ) -> Result<String,String>
@ -1012,11 +1009,20 @@ impl Routine {
{ // [x] End of Loop iteration { // [x] End of Loop iteration
let mut a = trg_routine_ar.write().await; 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; a.complete_iterations += 1;
if let Some(i) = a.remaining_iterations { if let Some(i) = a.remaining_iterations {
if i > 0 { a.remaining_iterations = Some(i-1) ; } if i > 0 { a.remaining_iterations = Some(i-1) ; }
else { break ; } // if remaining iterations is 0, exit else { break ; } // if remaining iterations is 0, exit
} }
} }
// [x] End of Loop Validation // [x] End of Loop Validation
@ -1078,16 +1084,21 @@ impl Routine {
trg_routine_ar 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); return Ok(trg_routine_arout);
} }
async fn loopbody(&self) async fn loopbody(&self)
// [x] => 03.27 - COMPLETED // [x] => 03.27 - COMPLETED
{ {
@ -1106,18 +1117,24 @@ impl Routine {
).await; ).await;
} }
pub async fn stop(&self) -> Result<String,String> pub async fn stop(&mut self) -> Result<String,String>
// [ ] => 03.27 - WIP - NOT IMPLEMENTED // [ ] => 03.27 - REVIEW FOR COMPLETION
{ {
let self_rw = Arc::new(RwLock::new(self)); let self_rw = Arc::new(RwLock::new(self));
let self_lock = self_rw.read().await;
{
let mut self_lock = self_rw.write().await;
self_lock.internal_signal = RoutineSignal::Stopping;
}
let self_lock = self_rw.read().await;
botlog::trace( botlog::trace(
format!( format!(
"[ERROR][Routine NOT IMPLEMENTED] {} in {}", "[ROUTINE][Sent Gracefully Stopp Signal] {} in {}",
self_lock.name,self_lock.channel.0 self_lock.name,self_lock.channel.0
) )
.as_str(), .as_str(),
@ -1130,37 +1147,24 @@ impl Routine {
Log::flush(); Log::flush();
Err("NOT IMPLEMENTED".to_string()) Ok("Sent Gracefully Stop Signal".to_string())
}
pub async fn restart( // botlog::trace(
&self, // format!(
_force : bool // "[ERROR][Routine NOT IMPLEMENTED] {} in {}",
) -> Result<String,String> // self_lock.name,self_lock.channel.0
// [ ] => 03.27 - WIP - NOT IMPLEMENTED // )
{ // .as_str(),
// force flag aborts the routine immediately (like cancel()) // Some(format!(
// "Routine > start() > (In Tokio Spawn) > {:?}",
// self_lock.module
// )),
// Some(&self_lock.parent_params.msg),
// );
// Log::flush();
let self_rw = Arc::new(RwLock::new(self)); // Err("NOT IMPLEMENTED".to_string())
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 async fn cancel(&self) -> Result<String,String> pub async fn cancel(&self) -> Result<String,String>
@ -1194,6 +1198,48 @@ impl Routine {
Err("NOT IMPLEMENTED".to_string()) 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())
}
} }