Wire native runtime flows into GPUI runs
This commit is contained in:
1 parent
686140ae55
commit
36ccb2c08f
12 files changed
+930
-49
No files matched your search
@@ -6,6 +6,15 @@ use std::{
|
||||
process::{Child, ChildStdin, ChildStdout, Command, Stdio},
|
||||
};
|
||||
|
||||
pub struct PiBridgeWriter {
|
||||
stdin: ChildStdin,
|
||||
}
|
||||
|
||||
pub struct PiBridgeEventStream {
|
||||
child: Child,
|
||||
stdout: BufReader<ChildStdout>,
|
||||
}
|
||||
|
||||
pub struct PiBridgeClient {
|
||||
child: Child,
|
||||
stdin: ChildStdin,
|
||||
@@ -14,60 +23,32 @@ pub struct PiBridgeClient {
|
||||
|
||||
impl PiBridgeClient {
|
||||
pub fn spawn(command: PathBuf, args: &[String], working_dir: Option<PathBuf>) -> Result<Self> {
|
||||
let mut process = Command::new(&command);
|
||||
process
|
||||
.args(args)
|
||||
.stdin(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::inherit());
|
||||
|
||||
if let Some(dir) = working_dir {
|
||||
process.current_dir(dir);
|
||||
}
|
||||
|
||||
let mut child = process
|
||||
.spawn()
|
||||
.with_context(|| format!("failed to spawn Pi Mono sidecar at {}", command.display()))?;
|
||||
let stdin = child
|
||||
.stdin
|
||||
.take()
|
||||
.context("Pi Mono sidecar stdin is unavailable")?;
|
||||
let stdout = child
|
||||
.stdout
|
||||
.take()
|
||||
.context("Pi Mono sidecar stdout is unavailable")?;
|
||||
let (child, stdin, stdout) = spawn_process(command, args, working_dir)?;
|
||||
Ok(Self {
|
||||
child,
|
||||
stdin,
|
||||
stdout: BufReader::new(stdout),
|
||||
stdout,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn spawn_split(
|
||||
command: PathBuf,
|
||||
args: &[String],
|
||||
working_dir: Option<PathBuf>,
|
||||
) -> Result<(PiBridgeWriter, PiBridgeEventStream)> {
|
||||
let (child, stdin, stdout) = spawn_process(command, args, working_dir)?;
|
||||
Ok((
|
||||
PiBridgeWriter { stdin },
|
||||
PiBridgeEventStream { child, stdout },
|
||||
))
|
||||
}
|
||||
|
||||
pub fn send(&mut self, message: &ClientRequest) -> Result<()> {
|
||||
let payload =
|
||||
serde_json::to_vec(message).context("failed to serialize Pi bridge request")?;
|
||||
self.stdin
|
||||
.write_all(&payload)
|
||||
.context("failed to write Pi bridge request")?;
|
||||
self.stdin
|
||||
.write_all(b"\n")
|
||||
.context("failed to terminate Pi bridge request")?;
|
||||
self.stdin
|
||||
.flush()
|
||||
.context("failed to flush Pi bridge request")?;
|
||||
Ok(())
|
||||
write_request(&mut self.stdin, message)
|
||||
}
|
||||
|
||||
pub fn read_event(&mut self) -> Result<RuntimeEvent> {
|
||||
let mut line = String::new();
|
||||
let bytes = self
|
||||
.stdout
|
||||
.read_line(&mut line)
|
||||
.context("failed to read Pi bridge event")?;
|
||||
if bytes == 0 {
|
||||
return Err(anyhow::anyhow!("Pi Mono sidecar closed stdout"));
|
||||
}
|
||||
serde_json::from_str(line.trim()).context("failed to decode Pi bridge event")
|
||||
read_event(&mut self.stdout)
|
||||
}
|
||||
|
||||
pub fn wait(&mut self) -> Result<()> {
|
||||
@@ -77,3 +58,75 @@ impl PiBridgeClient {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl PiBridgeWriter {
|
||||
pub fn send(&mut self, message: &ClientRequest) -> Result<()> {
|
||||
write_request(&mut self.stdin, message)
|
||||
}
|
||||
}
|
||||
|
||||
impl PiBridgeEventStream {
|
||||
pub fn read_event(&mut self) -> Result<RuntimeEvent> {
|
||||
read_event(&mut self.stdout)
|
||||
}
|
||||
|
||||
pub fn wait(&mut self) -> Result<()> {
|
||||
self.child
|
||||
.wait()
|
||||
.context("failed while waiting for Pi Mono sidecar")?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn spawn_process(
|
||||
command: PathBuf,
|
||||
args: &[String],
|
||||
working_dir: Option<PathBuf>,
|
||||
) -> Result<(Child, ChildStdin, BufReader<ChildStdout>)> {
|
||||
let mut process = Command::new(&command);
|
||||
process
|
||||
.args(args)
|
||||
.stdin(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::inherit());
|
||||
|
||||
if let Some(dir) = working_dir {
|
||||
process.current_dir(dir);
|
||||
}
|
||||
|
||||
let mut child = process
|
||||
.spawn()
|
||||
.with_context(|| format!("failed to spawn Pi Mono sidecar at {}", command.display()))?;
|
||||
let stdin = child
|
||||
.stdin
|
||||
.take()
|
||||
.context("Pi Mono sidecar stdin is unavailable")?;
|
||||
let stdout = child
|
||||
.stdout
|
||||
.take()
|
||||
.context("Pi Mono sidecar stdout is unavailable")?;
|
||||
Ok((child, stdin, BufReader::new(stdout)))
|
||||
}
|
||||
|
||||
fn write_request(stdin: &mut ChildStdin, message: &ClientRequest) -> Result<()> {
|
||||
let payload = serde_json::to_vec(message).context("failed to serialize Pi bridge request")?;
|
||||
stdin
|
||||
.write_all(&payload)
|
||||
.context("failed to write Pi bridge request")?;
|
||||
stdin
|
||||
.write_all(b"\n")
|
||||
.context("failed to terminate Pi bridge request")?;
|
||||
stdin.flush().context("failed to flush Pi bridge request")?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn read_event(stdout: &mut BufReader<ChildStdout>) -> Result<RuntimeEvent> {
|
||||
let mut line = String::new();
|
||||
let bytes = stdout
|
||||
.read_line(&mut line)
|
||||
.context("failed to read Pi bridge event")?;
|
||||
if bytes == 0 {
|
||||
return Err(anyhow::anyhow!("Pi Mono sidecar closed stdout"));
|
||||
}
|
||||
serde_json::from_str(line.trim()).context("failed to decode Pi bridge event")
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
pub mod client;
|
||||
pub mod protocol;
|
||||
|
||||
pub use client::PiBridgeClient;
|
||||
pub use client::{PiBridgeClient, PiBridgeEventStream, PiBridgeWriter};
|
||||
pub use protocol::*;
|
||||
Reference in new issue
Block a user