📦 ♻️ Refactor a bunch of stuff; debian packaging
This commit is contained in:
parent
a0091235a4
commit
a67a677a1a
15 changed files with 1119 additions and 149 deletions
154
src/process.rs
154
src/process.rs
|
|
@ -6,6 +6,7 @@ use tokio::{
|
|||
sync::mpsc::UnboundedSender,
|
||||
};
|
||||
use tokio_util::sync::CancellationToken;
|
||||
use tracing::{Instrument, Span};
|
||||
|
||||
pub enum ProcessEvent {
|
||||
Started,
|
||||
|
|
@ -27,82 +28,91 @@ impl ProcessHandler {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn run(self, executable: impl ToString, args: Vec<String>, vars: Vec<(String, String)>) {
|
||||
pub fn run(
|
||||
self,
|
||||
executable: impl ToString,
|
||||
args: Vec<String>,
|
||||
vars: Vec<(String, String)>,
|
||||
span: &Span,
|
||||
) {
|
||||
let executable = executable.to_string();
|
||||
tokio::spawn(async move {
|
||||
let mut child = match Command::new(&executable)
|
||||
.args(&args)
|
||||
.stdin(Stdio::null())
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::piped())
|
||||
.envs(vars)
|
||||
.kill_on_drop(true)
|
||||
.spawn()
|
||||
{
|
||||
Ok(child) => child,
|
||||
Err(error) => {
|
||||
error!(
|
||||
"failed to launch '{} {}': {}",
|
||||
executable,
|
||||
args.join(" "),
|
||||
error
|
||||
);
|
||||
return;
|
||||
}
|
||||
};
|
||||
let mut stdout = BufReader::new(child.stdout.take().unwrap()).lines();
|
||||
let mut stderr = BufReader::new(child.stderr.take().unwrap()).lines();
|
||||
std::mem::drop(self.tx.send(ProcessEvent::Started));
|
||||
loop {
|
||||
tokio::select! {
|
||||
status = child.wait() => match status {
|
||||
Ok(status) => {
|
||||
info!("'{}' exited with status {}", executable, status);
|
||||
std::mem::drop(self.tx.send(ProcessEvent::Ended(Some(status))));
|
||||
return;
|
||||
}
|
||||
Err(error) => {
|
||||
error!(
|
||||
"failed to wait for '{}' to end: {}",
|
||||
executable,
|
||||
error
|
||||
);
|
||||
return;
|
||||
}
|
||||
},
|
||||
line = stdout.next_line() => match line {
|
||||
Ok(Some(line)) => {
|
||||
std::mem::drop(self.tx.send(ProcessEvent::Stdout(line)));
|
||||
},
|
||||
Ok(None) => (),
|
||||
Err(error) => {
|
||||
warn!(
|
||||
"failed to get stdout line from '{}': {}",
|
||||
executable,
|
||||
error
|
||||
);
|
||||
}
|
||||
},
|
||||
line = stderr.next_line() => match line {
|
||||
Ok(Some(line)) => {
|
||||
std::mem::drop(self.tx.send(ProcessEvent::Stderr(line)));
|
||||
},
|
||||
Ok(None) => (),
|
||||
Err(error) => {
|
||||
warn!(
|
||||
"failed to get stderr line from '{}': {}",
|
||||
executable,
|
||||
error
|
||||
);
|
||||
}
|
||||
},
|
||||
_ = self.cancellation_token.cancelled() => {
|
||||
warn!("exiting '{}': cancelled", executable);
|
||||
std::mem::drop(self.tx.send(ProcessEvent::Ended(None)));
|
||||
tokio::spawn(
|
||||
async move {
|
||||
let mut child = match Command::new(&executable)
|
||||
.args(&args)
|
||||
.stdin(Stdio::null())
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::piped())
|
||||
.envs(vars)
|
||||
.kill_on_drop(true)
|
||||
.spawn()
|
||||
{
|
||||
Ok(child) => child,
|
||||
Err(error) => {
|
||||
error!(
|
||||
"failed to launch '{} {}': {}",
|
||||
executable,
|
||||
args.join(" "),
|
||||
error
|
||||
);
|
||||
return;
|
||||
}
|
||||
};
|
||||
let mut stdout = BufReader::new(child.stdout.take().unwrap()).lines();
|
||||
let mut stderr = BufReader::new(child.stderr.take().unwrap()).lines();
|
||||
std::mem::drop(self.tx.send(ProcessEvent::Started));
|
||||
loop {
|
||||
tokio::select! {
|
||||
status = child.wait() => match status {
|
||||
Ok(status) => {
|
||||
info!("'{}' exited with status {}", executable, status);
|
||||
std::mem::drop(self.tx.send(ProcessEvent::Ended(Some(status))));
|
||||
return;
|
||||
}
|
||||
Err(error) => {
|
||||
error!(
|
||||
"failed to wait for '{}' to end: {}",
|
||||
executable,
|
||||
error
|
||||
);
|
||||
return;
|
||||
}
|
||||
},
|
||||
line = stdout.next_line() => match line {
|
||||
Ok(Some(line)) => {
|
||||
std::mem::drop(self.tx.send(ProcessEvent::Stdout(line)));
|
||||
},
|
||||
Ok(None) => (),
|
||||
Err(error) => {
|
||||
warn!(
|
||||
"failed to get stdout line from '{}': {}",
|
||||
executable,
|
||||
error
|
||||
);
|
||||
}
|
||||
},
|
||||
line = stderr.next_line() => match line {
|
||||
Ok(Some(line)) => {
|
||||
std::mem::drop(self.tx.send(ProcessEvent::Stderr(line)));
|
||||
},
|
||||
Ok(None) => (),
|
||||
Err(error) => {
|
||||
warn!(
|
||||
"failed to get stderr line from '{}': {}",
|
||||
executable,
|
||||
error
|
||||
);
|
||||
}
|
||||
},
|
||||
_ = self.cancellation_token.cancelled() => {
|
||||
warn!("exiting '{}': cancelled", executable);
|
||||
std::mem::drop(self.tx.send(ProcessEvent::Ended(None)));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
.instrument(span.clone()),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue