Improved architecture with signle mutex
This commit is contained in:
@@ -1,31 +1,25 @@
|
||||
use std::{path::PathBuf, process::Stdio};
|
||||
|
||||
use pulse_sdk::{
|
||||
map_postcard_err,
|
||||
strategy::{StrategyEngineMessage, StrategyManifest, StrategyMessage},
|
||||
};
|
||||
use tokio::{
|
||||
io::{AsyncReadExt, AsyncWriteExt},
|
||||
process::{Child, ChildStdout},
|
||||
sync::Mutex,
|
||||
process::{Child, ChildStdout, Command},
|
||||
};
|
||||
#[derive(Debug)]
|
||||
pub struct StrategyChild {
|
||||
pub manifest: Mutex<StrategyManifest>,
|
||||
pub stdout: Mutex<ChildStdout>,
|
||||
pub process: Mutex<Child>,
|
||||
pub manifest: StrategyManifest,
|
||||
pub child: Child,
|
||||
}
|
||||
|
||||
impl StrategyChild {
|
||||
pub fn new(mut child: Child, manifest: StrategyManifest) -> Self {
|
||||
Self {
|
||||
stdout: Mutex::new(child.stdout.take().expect("Failed to obtain child stdout")),
|
||||
process: Mutex::new(child),
|
||||
manifest: Mutex::new(manifest),
|
||||
}
|
||||
pub fn new(child: Child, manifest: StrategyManifest) -> Self {
|
||||
Self { child, manifest }
|
||||
}
|
||||
|
||||
pub async fn recv(&self) -> tokio::io::Result<Option<StrategyMessage>> {
|
||||
let mut stdout = self.stdout.lock().await;
|
||||
|
||||
pub async fn read(stdout: &mut ChildStdout) -> tokio::io::Result<Option<StrategyMessage>> {
|
||||
let mut len_buf = [0u8; size_of::<usize>()];
|
||||
let size = stdout.read_exact(&mut len_buf).await?;
|
||||
|
||||
@@ -42,14 +36,13 @@ impl StrategyChild {
|
||||
Ok(Some(map_postcard_err(postcard::from_bytes(&buffer))?))
|
||||
}
|
||||
|
||||
pub async fn send(&self, msg: &StrategyEngineMessage) -> tokio::io::Result<()> {
|
||||
pub async fn send(&mut self, msg: &StrategyEngineMessage) -> tokio::io::Result<()> {
|
||||
self.send_raw(&map_postcard_err(postcard::to_allocvec(msg))?)
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn send_raw(&self, msg: &[u8]) -> tokio::io::Result<()> {
|
||||
let mut process = self.process.lock().await;
|
||||
let stdin = process.stdin.as_mut().unwrap();
|
||||
pub async fn send_raw(&mut self, msg: &[u8]) -> tokio::io::Result<()> {
|
||||
let stdin = self.child.stdin.as_mut().unwrap();
|
||||
|
||||
stdin.write_all(&msg.len().to_le_bytes()).await?;
|
||||
stdin.write_all(msg).await?;
|
||||
@@ -57,20 +50,22 @@ impl StrategyChild {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn reload(
|
||||
&self,
|
||||
mut child: Child,
|
||||
manifest: StrategyManifest,
|
||||
) -> tokio::io::Result<()> {
|
||||
let mut process = self.process.lock().await;
|
||||
|
||||
process.kill().await?;
|
||||
|
||||
*self.stdout.lock().await = child.stdout.take().expect("Failed to obtain child stdout");
|
||||
*self.manifest.lock().await = manifest;
|
||||
*process = child;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
pub fn get_manifest<'de, M: serde::Deserialize<'de>>(
|
||||
strategy_dir: &PathBuf,
|
||||
strategy_path: &PathBuf,
|
||||
manifest: &'de [u8],
|
||||
) -> tokio::io::Result<(Child, M)> {
|
||||
Ok((
|
||||
Command::new("bash")
|
||||
.arg(strategy_path)
|
||||
.current_dir(strategy_dir)
|
||||
.stdin(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::inherit())
|
||||
.spawn()?,
|
||||
toml::from_slice(manifest)
|
||||
.map_err(|v| tokio::io::Error::new(std::io::ErrorKind::InvalidInput, v.to_string()))?,
|
||||
))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user