77 lines
2.1 KiB
Rust
77 lines
2.1 KiB
Rust
use pulse_sdk::{
|
|
map_postcard_err,
|
|
strategy::{StrategyEngineMessage, StrategyManifest, StrategyMessage},
|
|
};
|
|
use tokio::{
|
|
io::{AsyncReadExt, AsyncWriteExt},
|
|
process::{Child, ChildStdout},
|
|
sync::Mutex,
|
|
};
|
|
#[derive(Debug)]
|
|
pub struct StrategyChild {
|
|
pub manifest: Mutex<StrategyManifest>,
|
|
pub stdout: Mutex<ChildStdout>,
|
|
pub process: Mutex<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 async fn recv(&self) -> tokio::io::Result<Option<StrategyMessage>> {
|
|
let mut stdout = self.stdout.lock().await;
|
|
|
|
let mut len_buf = [0u8; size_of::<usize>()];
|
|
let size = stdout.read_exact(&mut len_buf).await?;
|
|
|
|
let len = usize::from_le_bytes(len_buf);
|
|
|
|
if size == 0 || len == 0 {
|
|
return Ok(None);
|
|
}
|
|
|
|
let mut buffer = vec![0u8; len];
|
|
|
|
stdout.read_exact(&mut buffer).await?;
|
|
|
|
Ok(Some(map_postcard_err(postcard::from_bytes(&buffer))?))
|
|
}
|
|
|
|
pub async fn send(&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();
|
|
|
|
stdin.write_all(&msg.len().to_le_bytes()).await?;
|
|
stdin.write_all(msg).await?;
|
|
stdin.flush().await?;
|
|
|
|
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(())
|
|
}
|
|
}
|