Added plugin lifecycle events

added lifecycle events to the plugin entry.

This allows plugins to be in a stopped paused or running state
This commit is contained in:
michael-bailey 2022-04-10 17:22:34 +01:00
parent c3c7d2a381
commit 8dd22730b7
3 changed files with 79 additions and 17 deletions

View File

@ -37,17 +37,19 @@ impl IPlugin for ExamplePlugin {
async fn run(&self) {
println!("Example!!!");
sleep(Duration::new(1, 0));
if let mut a = self.number.lock().await {
*a += 1;
println!("[ExamplePlugin]: example run {}", *a);
}
let mut a = self.number.lock().await;
*a = a.overflowing_add(1).0;
println!("[ExamplePlugin]: example run {}", *a);
}
fn deinit(&self) {
todo!()
if let Some(mut lock) = self.number.try_lock() {
*lock = 0;
}
}
async fn event(&self) {
todo!()
println!("Not Implemented");
}
}

View File

@ -5,12 +5,18 @@ use tokio::{
};
use std::io::{SeekFrom, ErrorKind};
use std::mem;
use std::ops::ControlFlow::Break;
use std::sync::Arc;
use std::time::Duration;
use tokio::sync::Mutex;
use tokio::time::sleep;
use crate::plugin::plugin::Plugin;
use crate::plugin::plugin_entry::PluginExecutionState::{Paused, Running, Stopped};
pub type PluginEntryObj = Arc<PluginEntry>;
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Deserialize, Debug, Ord, PartialOrd, Eq, PartialEq)]
pub enum PluginPermission {
Read,
Write,
@ -18,6 +24,13 @@ pub enum PluginPermission {
None
}
#[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq)]
pub(crate) enum PluginExecutionState {
Running,
Paused,
Stopped,
}
/// # PluginEntry
/// a wrapper for plugins loaded into the server.
/// Used to provide an api for the plugin to use.
@ -29,6 +42,8 @@ pub struct PluginEntry {
client_manager_permission: PluginPermission,
client_permission: PluginPermission,
state: Arc<Mutex<PluginExecutionState>>,
plugin: Plugin
}
@ -41,20 +56,65 @@ impl PluginEntry {
client_manager_permission: PluginPermission::None,
client_permission: PluginPermission::None,
state: Arc::new(Mutex::new(Stopped)),
plugin
})
}
pub(crate) async fn getState(&self) -> PluginExecutionState {
*self.state.lock().await
}
pub fn start(&self) {
let cont = self.plugin.clone();
let state = self.state.clone();
tokio::spawn(async move {
println!("[PluginEntry:start] starting plugin: {:?}", cont.details().id);
cont.init();
loop {
// Todo: Add code to stop loop once finished
cont.run().await;
let local_state = state.clone();
let mut lock = local_state.lock().await;
match *lock {
Running => return,
Paused => {*lock = Running; return},
Stopped => {
tokio::spawn(async move {
cont.init();
let mut lock = state.lock().await;
*lock = Running;
loop {
match *lock {
Running => cont.run().await,
Paused => sleep(Duration::new(1,0)).await,
Stopped => break,
}
}
cont.deinit()
}); return
},
}
});
}
pub fn pause(&self) {
let state = self.state.clone();
tokio::spawn(async move {
let mut lock = state.lock().await;
match *lock {
Running => {*lock = Paused; return},
Paused => return,
Stopped => return,
}
});
}
pub fn stop(&self) {
let state = self.state.clone();
tokio::spawn(async move {
let mut lock = state.lock().await;
match *lock {
Running => {*lock = Stopped; return},
Paused => {*lock = Stopped; return},
Stopped => return,
}
cont.deinit();
});
}
}

View File

@ -92,10 +92,10 @@ impl<Out: 'static> PluginManager<Out>
create_dir("./plugins").await?;
}
for i in self.plugins.lock().await.iter() {
i.start()
}
self.plugins.lock().await
.iter()
.for_each(|item| item.start());
Ok(())
Ok(())
}
}