pub fn get_or_spawn<KeyType: 'static>(
keyname: impl ToString,
spawn: impl FnOnce() -> Command,
) -> Result<PersistentChild>Expand description
A combination of the spawn ang get commands, letting
you “lazyly” spawn processes.
§Examples
use std::{
io::BufRead,
mem,
process::{Command, Stdio},
};
use duat::{
prelude::*,
process::{self, is_interrupt},
};
// Private key for processes.
struct Key;
struct PluginWithProcesses;
impl Plugin for PluginWithProcesses {
fn plug(self, _: &Plugins) {
let pname = "process1";
let mut child = process::get_or_spawn::<Key>(pname, || {
let mut command = Command::new("your-command-name");
command
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped());
command
})
.unwrap();
let mut stdout = child.stdout.take().unwrap();
let join_stdout = std::thread::spawn(move || {
let mut line = String::new();
loop {
match stdout.read_line(&mut line) {
// The Child has exited.
Ok(0) => break stdout,
Ok(_) => do_stuff_with_line(mem::take(&mut line)),
// Duat is about to reload.
Err(err) if is_interrupt(&err) => break stdout,
Err(err) => context::error!("{err}"),
}
}
});
let mut stderr = child.stderr.take().unwrap();
let join_stderr = std::thread::spawn(move || {
// Similar thing as above...
stderr
});
hook::add_once::<ConfigUnloaded>(move |_, _| {
let stdout = join_stdout.join().unwrap();
let stderr = join_stderr.join().unwrap();
child.stdout = Some(stdout);
child.stderr = Some(stderr);
process::store::<Key>(pname, child);
});
}
}