Files
pulse-trader/src/engine/store/strategy.rs
T

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(())
}
}