use std::boxed::Box; use std::fs::File; use std::io::Read; use std::path::PathBuf; use mio::{Poll, PollOpt, Ready}; use crate::app::App; use crate::proc::Proc; use crate::result::Result; #[derive(Debug, Deserialize)] pub struct Apps { pub app: Vec, } impl Apps { /// load apps from toml file pub fn load(p: PathBuf) -> Result { let path: String = p.display().to_string(); match File::open(p) { Ok(mut file) => { let mut buf = String::new(); if let Err(e) = file.read_to_string(&mut buf) { error!("unable to read apps file: {}", path); return Err(Box::new(e)); }; match toml::from_str(&buf) { Ok(t) => Ok(t), Err(e) => { error!("Invalid toml in apps file: {}", path); Err(Box::new(e)) } } } Err(e) => { error!("Unable to open apps file: {}", path); Err(Box::new(e)) } } } pub fn apps(&self) -> Vec { self.app.clone() } pub fn start(&self) -> (Vec, Option, Poll) { let mut procs: Vec = Vec::new(); let mut holds: Option = None; let poll = Poll::new().unwrap(); 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); error!("{:?}", 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); } poll.register(&proc.process, proc.token, Ready::all(), PollOpt::edge()) .unwrap(); procs.push(proc); } Err(e) => { error!("app failed to start: {}", name); error!("{:?}", e); } }; } } info!("holds: {:?}", holds); (procs, holds, poll) } }