tutti_core/process/
mod.rs1use futures_core::Stream;
2use std::fmt::Debug;
3use std::pin::Pin;
4use std::{path::PathBuf, time::Duration};
5
6pub mod unix;
7
8pub type BoxStream<T> = Pin<Box<dyn Stream<Item = T> + Send>>;
9
10#[derive(Clone, Debug)]
11pub struct CommandSpec {
12 pub name: String,
13 pub cmd: Vec<String>,
14 pub cwd: Option<PathBuf>,
15 pub env: Vec<(String, String)>,
16}
17
18#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
19pub struct ProcId(pub u64);
20
21pub struct Spawned {
22 pub id: ProcId,
23 pub pid: Option<u32>,
24 pub stdout: BoxStream<Vec<u8>>,
25 pub stderr: BoxStream<Vec<u8>>,
26}
27
28impl Debug for Spawned {
29 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
30 f.debug_struct("Spawned")
31 .field("id", &self.id)
32 .field("pid", &self.pid)
33 .field("stdout", &"<stream>")
34 .field("stderr", &"<stream>")
35 .finish()
36 }
37}
38
39#[async_trait::async_trait]
40pub trait ProcessManager: Send + Sync {
41 async fn spawn(&mut self, spec: CommandSpec) -> anyhow::Result<Spawned>;
43 async fn shutdown(&mut self, id: ProcId) -> anyhow::Result<()>;
45 async fn wait(&mut self, id: ProcId, d: Duration) -> anyhow::Result<Option<i32>>;
47 async fn kill(&mut self, id: ProcId) -> anyhow::Result<()>;
49}