You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
112 lines
2.4 KiB
112 lines
2.4 KiB
use std::fs::File;
|
|
use std::io::Read;
|
|
use std::path::PathBuf;
|
|
|
|
use crate::app::App;
|
|
use crate::proc::Proc;
|
|
use crate::result::Result;
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
pub struct Apps {
|
|
pub app: Vec<App>,
|
|
}
|
|
|
|
impl Apps {
|
|
pub fn load<T: Into<PathBuf>>(p: T) -> Result<Self> {
|
|
let mut file = File::open(p.into())?;
|
|
let mut buf = String::new();
|
|
file.read_to_string(&mut buf)?;
|
|
Ok(toml::from_str(&buf)?)
|
|
}
|
|
|
|
pub fn apps(&self) -> Vec<App> {
|
|
self.app.clone()
|
|
}
|
|
|
|
pub fn start(&self) -> (Vec<Proc>, Option<i8>) {
|
|
let mut procs: Vec<Proc> = Vec::new();
|
|
let mut holds: Option<i8> = None;
|
|
|
|
for app in self.apps() {
|
|
if app.wait.unwrap_or(false) {
|
|
if let Err(e) = app.wait_start() {
|
|
error!("app failed to start: {}: {:?}", &app.name, e);
|
|
}
|
|
} else {
|
|
let name = app.name.clone();
|
|
match Proc::start(app) {
|
|
Ok(proc) => {
|
|
if proc.app.hold.unwrap_or(false) {
|
|
holds = Some(holds.unwrap_or(0) + 1);
|
|
}
|
|
procs.push(proc);
|
|
}
|
|
Err(e) => error!("app failed to start: {}: {:?}", name, e),
|
|
};
|
|
}
|
|
}
|
|
|
|
(procs, holds)
|
|
}
|
|
|
|
pub fn run(&self, procs: Vec<Proc>, holds: Option<i8>) -> Result<()> {
|
|
let mut procs = procs;
|
|
let mut holds = holds;
|
|
|
|
if holds.unwrap_or(0) < 1 {
|
|
error!("no holds configured");
|
|
return Ok(());
|
|
}
|
|
|
|
while holds > Some(0) {
|
|
let mut newprocs: Vec<Proc> = Vec::new();
|
|
|
|
while let Some(mut proc) = procs.pop() {
|
|
match proc.child.try_wait() {
|
|
Ok(Some(status)) => {
|
|
let hold = proc.app.hold.unwrap_or(false);
|
|
if proc.app.handle_exit(status) {
|
|
let name = proc.app.name.clone();
|
|
match Proc::start(proc.app) {
|
|
Ok(p) => newprocs.push(p),
|
|
Err(e) => {
|
|
error!("error restarting {}: {:?}", name, e);
|
|
if hold {
|
|
holds = Some(holds.unwrap_or(0) - 1);
|
|
}
|
|
}
|
|
};
|
|
} else if hold {
|
|
holds = Some(holds.unwrap_or(0) - 1);
|
|
}
|
|
}
|
|
Ok(None) => {
|
|
if let Some(s) = &proc.check_stdout() {
|
|
for line in s.lines() {
|
|
info!("[{}] stdout: {}", &proc.app.name, line);
|
|
}
|
|
}
|
|
if let Some(s) = &proc.check_stderr() {
|
|
for line in s.lines() {
|
|
info!("[{}] stderr: {}", &proc.app.name, line);
|
|
}
|
|
}
|
|
newprocs.push(proc);
|
|
}
|
|
Err(e) => error!("error: {:?}", e),
|
|
}
|
|
}
|
|
procs = newprocs;
|
|
}
|
|
|
|
info!("shutting down");
|
|
for mut proc in procs {
|
|
info!("stopping {}", &proc.app.name);
|
|
let _ = proc.child.kill();
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
}
|