Improved architecture with signle mutex

This commit is contained in:
2026-07-30 05:56:59 +02:00
parent 535c6a2964
commit 7f1e3f8d7d
7 changed files with 106 additions and 112 deletions
+28 -33
View File
@@ -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()))?,
))
}