diff --git a/src/engine/engine.rs b/src/engine/engine.rs index 52a5f2c..c3ce821 100644 --- a/src/engine/engine.rs +++ b/src/engine/engine.rs @@ -1,5 +1,5 @@ use crate::{ - store::{accounts::AccountList, config::Config, plugin::StrategyPair}, + store::{accounts::AccountList, config::Config, plugin::StrategyEngine}, terminal::TerminalServer, }; use pulse_wire::prelude::*; @@ -11,16 +11,14 @@ pub struct Engine { pub terminal_server: Arc, pub config: Arc>, pub accounts: Arc>, - pub strategy: Arc>, + pub strategy: Arc, } impl Engine { pub async fn new() -> tokio::io::Result> { let config = Config::new().await?; let accounts = Arc::new(Mutex::new(AccountList::new().await?)); - let strategy = Arc::new(Mutex::new( - StrategyPair::new(&config.strategy, &config.risk).await?, - )); + let strategy = Arc::new(StrategyEngine::new(&config.strategy, &config.risk).await?); let config = Arc::new(Mutex::new(config)); Ok(Arc::new_cyclic(|engine| Self { diff --git a/src/engine/store/plugin.rs b/src/engine/store/plugin.rs index b014315..a589dfe 100644 --- a/src/engine/store/plugin.rs +++ b/src/engine/store/plugin.rs @@ -7,10 +7,13 @@ use pulse_wire::{ StrategyMessage, }, }; + use tokio::{ fs, io::{AsyncReadExt, AsyncWriteExt}, process::Command, + sync::Mutex, + task::JoinHandle, }; use crate::store::pulse_plugin; @@ -100,3 +103,40 @@ impl StrategyPair { }) } } + +#[derive(Debug)] +pub struct StrategyEngine { + pub pair: Mutex, + + pub strategy_handle: Mutex>>, + pub risk_handle: Mutex>>, +} + +impl StrategyEngine { + pub async fn new(strategy_id: &str, risk_id: &str) -> tokio::io::Result { + Ok(Self { + pair: Mutex::new(StrategyPair::new(strategy_id, risk_id).await?), + strategy_handle: Mutex::new(None), + risk_handle: Mutex::new(None), + }) + } + + pub async fn reload(&self, strategy_id: &str, risk_id: &str) -> tokio::io::Result<()> { + if let Some(handle) = &*self.strategy_handle.lock().await { + handle.abort(); + } + + if let Some(handle) = &*self.risk_handle.lock().await { + handle.abort(); + } + + let mut pair = self.pair.lock().await; + + pair.strategy.process.kill().await?; + pair.risk.process.kill().await?; + + *pair = StrategyPair::new(strategy_id, risk_id).await?; + + Ok(()) + } +}