switch to mio so we can not block

master
rasul 5 years ago
parent 121840498e
commit e330660ccb

137
Cargo.lock generated

@ -188,6 +188,20 @@ name = "fuchsia-cprng"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "fuchsia-zircon"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "fuchsia-zircon-sys"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "getopts"
version = "0.2.21"
@ -196,11 +210,33 @@ dependencies = [
"unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "iovec"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "kernel32-sys"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "lazycell"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "libc"
version = "0.2.62"
@ -214,6 +250,67 @@ dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "mio"
version = "0.6.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "mio-child-process"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)",
"mio-extras 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "mio-extras"
version = "2.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "miow"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "net2"
version = "0.2.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "nodrop"
version = "0.1.14"
@ -357,6 +454,11 @@ dependencies = [
"syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "slab"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "sup"
version = "0.1.0"
@ -367,6 +469,8 @@ dependencies = [
"fern 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)",
"getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)",
"mio-child-process 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"toml 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
@ -421,6 +525,11 @@ name = "unicode-xid"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi"
version = "0.3.8"
@ -430,6 +539,11 @@ dependencies = [
"winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "winapi-build"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
@ -451,6 +565,15 @@ dependencies = [
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "ws2_32-sys"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[metadata]
"checksum approx 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08abcc3b4e9339e33a3d0a5ed15d84a687350c05689d825e0f6655eef9e76a94"
"checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee"
@ -476,10 +599,20 @@ dependencies = [
"checksum failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0bc225b78e0391e4b8683440bf2e63c2deeeb2ce5189eab46e2b68c6d3725d08"
"checksum fern 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e69ab0d5aca163e388c3a49d284fed6c3d0810700e77c5ae2756a50ec1a4daaa"
"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
"checksum getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)" = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5"
"checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
"checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
"checksum libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)" = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba"
"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
"checksum mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)" = "302dec22bcf6bae6dfb69c647187f4b4d0fb6f535521f7bc022430ce8e12008f"
"checksum mio-child-process 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "93e2c2ad8adb5feea8031c9b23b17e359dd65a75b32214660686edec80be0bf4"
"checksum mio-extras 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19"
"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
"checksum nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
"checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09"
"checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31"
@ -498,13 +631,17 @@ dependencies = [
"checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
"checksum serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)" = "9796c9b7ba2ffe7a9ce53c2287dfc48080f4b2b362fcc245a259b3a7201119dd"
"checksum serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)" = "4b133a43a1ecd55d4086bd5b4dc6c1751c68b1bfbeba7a5040442022c7e7c02e"
"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
"checksum syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "66850e97125af79138385e9b88339cbcd037e3f28ceab8c5ad98e64f0f1f80bf"
"checksum synstructure 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3f085a5855930c0441ca1288cf044ea4aecf4f43a91668abdb870b4ba546a203"
"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"
"checksum toml 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c7aabe75941d914b72bf3e5d3932ed92ce0664d49d8432305a8b547c37227724"
"checksum unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7007dbd421b92cc6e28410fe7362e2e0a2503394908f417b68ec8d1c364c4e20"
"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
"checksum winconsole 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ef84b96d10db72dd980056666d7f1e7663ce93d82fa33b63e71c966f4cf5032"
"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"

@ -11,6 +11,8 @@ dirs = "2.0"
fern = { version = "0.5", features = ["colored"] }
getopts = "0.2"
log = "0.4"
mio = "0.6"
mio-child-process = "0.2"
serde = "1.0"
serde_derive = "1.0"
toml = "0.5"

@ -2,19 +2,29 @@ use std::process::{Command, ExitStatus};
use crate::result::Result;
/// structure to define an app config
#[derive(Clone, Debug, Deserialize)]
pub struct App {
/// name of the app
pub name: String,
/// path/command to run
pub command: String,
/// arguments
pub args: Vec<String>,
/// should the app be restarted if it exits successfully
pub restart_on_success: Option<bool>,
/// should the app be restarted if it exits unsuccessfully
pub restart_on_failure: Option<bool>,
/// should the app be restarted if it is terminated
pub restart_on_terminate: Option<bool>,
/// on sup startup, should we wait for this app to run before continuting
pub wait: Option<bool>,
/// should this app keep sup from exiting, if it's running
pub hold: Option<bool>,
}
impl App {
/// start the application and wait for it to exit
pub fn wait_start(&self) -> Result<()> {
info!("starting application {}", &self.name);
@ -41,7 +51,8 @@ impl App {
}
}
pub fn handle_exit(&self, status: ExitStatus) -> bool {
/// see if the app should be restarted
pub fn check_restart(&self, status: ExitStatus) -> bool {
if status.success() {
info!("application exited: {}", &self.name);
self.restart_on_success.unwrap_or(false)

@ -3,6 +3,8 @@ 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;
@ -13,8 +15,10 @@ pub struct Apps {
}
impl Apps {
/// load apps from toml file
pub fn load(p: PathBuf) -> Result<Self> {
let path: String = p.display().to_string();
match File::open(p) {
Ok(mut file) => {
let mut buf = String::new();
@ -43,10 +47,12 @@ impl Apps {
self.app.clone()
}
pub fn start(&self) -> (Vec<Proc>, Option<i8>) {
pub fn start(&self) -> (Vec<Proc>, Option<i8>, Poll) {
let mut procs: Vec<Proc> = Vec::new();
let mut holds: Option<i8> = None;
let poll = Poll::new().unwrap();
for app in self.apps() {
if app.wait.unwrap_or(false) {
if let Err(e) = app.wait_start() {
@ -60,6 +66,8 @@ impl Apps {
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) => {
@ -70,60 +78,8 @@ impl Apps {
}
}
(procs, holds)
}
pub fn run(&self, procs: Vec<Proc>, holds: Option<i8>) -> Result<Vec<Proc>> {
let mut procs = procs;
let mut holds = holds;
if holds.unwrap_or(0) < 1 {
error!("no holds configured");
return Ok(procs);
}
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);
error!("{:?}", 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!("holds: {:?}", holds);
Ok(procs)
(procs, holds, poll)
}
}

@ -54,7 +54,7 @@ impl Config {
let log_file = if let Some(f) = matches.opt_str("f") {
PathBuf::from(f)
} else {
let mut p = PathBuf::new();
let mut p = PathBuf::from(&config_directory);
p.push("sup.log");
p
};

@ -2,13 +2,13 @@ use std::path::PathBuf;
use chrono::Local;
use colored::Colorize;
use fern::{Dispatch, log_file};
use fern::colors::{Color, ColoredLevelConfig};
use fern::{log_file, Dispatch};
use log::LevelFilter;
use crate::result::Result;
pub fn setup_logger(logfile: PathBuf, level: LevelFilter) -> Result<()> {
pub fn setup(logfile: PathBuf, level: LevelFilter) -> Result<()> {
Dispatch::new()
.format(|out, message, record| {
let colors = ColoredLevelConfig::new()
@ -20,7 +20,11 @@ pub fn setup_logger(logfile: PathBuf, level: LevelFilter) -> Result<()> {
out.finish(format_args!(
"{} {} {}",
Local::now().format("%Y-%m-%dT%H:%M:%S%.3f%z").to_string().white().bold(),
Local::now()
.format("%Y-%m-%dT%H:%M:%S%.3f%z")
.to_string()
.white()
.bold(),
colors.color(record.level()),
message
))

@ -5,6 +5,8 @@ extern crate fern;
extern crate getopts;
#[macro_use]
extern crate log;
extern crate mio;
extern crate mio_child_process;
extern crate serde;
#[macro_use]
extern crate serde_derive;
@ -16,6 +18,7 @@ mod config;
mod logger;
mod proc;
mod result;
mod run;
use std::path::PathBuf;
@ -23,11 +26,12 @@ use apps::Apps;
use config::Config;
use proc::Proc;
use result::Result;
use run::run;
fn main() {
let config = Config::from_args();
if let Err(e) = logger::setup_logger(config.log_file, config.log_level) {
if let Err(e) = logger::setup(config.log_file, config.log_level) {
println!("FATAL: Error initializing logger: {:?}", e);
std::process::exit(1);
}
@ -51,7 +55,7 @@ fn main() {
fn startup(apps_file: PathBuf) -> Result<Vec<Proc>> {
let apps = Apps::load(apps_file)?;
let (procs, holds) = apps.start();
let procs = apps.run(procs, holds)?;
let (procs, holds, poll) = apps.start();
let procs = run(procs, holds, poll)?;
Ok(procs)
}

@ -1,12 +1,16 @@
use std::io::Read;
use std::process::{Child, Command, Stdio};
use std::convert::TryInto;
use std::process::{Command, Stdio};
use mio::Token;
use mio_child_process::{CommandAsync, Process};
use crate::app::App;
use crate::result::Result;
pub struct Proc {
pub app: App,
pub child: Child,
pub process: Process,
pub token: Token,
}
impl Proc {
@ -18,55 +22,18 @@ impl Proc {
command.stderr(Stdio::piped());
command.args(&app.args);
let child = command.spawn()?;
let process = command.spawn_async()?;
let token = Token(process.id().try_into()?);
Ok(Proc { app, child })
Ok(Proc {
app,
process,
token,
})
}
pub fn stop(&mut self) {
info!("stopping {}", &self.app.name);
let _ = self.child.kill();
}
pub fn check_stdout(&mut self) -> Option<String> {
let child_stdout = self.child.stdout.as_mut();
if let Some(stdout) = child_stdout {
let mut buf = String::new();
match stdout.read_to_string(&mut buf) {
Ok(size) => {
if size > 0 {
return Some(buf);
} else {
return None;
}
}
Err(e) => {
error!("couldn't read stdout from {}: {:?}", &self.app.name, e);
return None;
}
}
}
None
}
pub fn check_stderr(&mut self) -> Option<String> {
let child_stderr = self.child.stderr.as_mut();
if let Some(stderr) = child_stderr {
let mut buf = String::new();
match stderr.read_to_string(&mut buf) {
Ok(size) => {
if size > 0 {
return Some(buf);
} else {
return None;
}
}
Err(e) => {
error!("couldn't read stderr from {}: {:?}", &self.app.name, e);
return None;
}
}
}
None
let _ = self.process.kill();
}
}

@ -0,0 +1,103 @@
use std::sync::mpsc::TryRecvError;
use mio::{Events, Poll, PollOpt, Ready, Token};
use mio_child_process::{ProcessEvent, StdioChannel};
use crate::proc::Proc;
use crate::result::Result;
/// check for holds and start the loop
pub fn run(procs: Vec<Proc>, holds: Option<i8>, poll: Poll) -> Result<Vec<Proc>> {
if holds.unwrap_or(0) < 1 {
error!("no holds configured");
return Ok(procs);
}
Ok(run_loop(procs, holds, poll))
}
/// restart an App, return the new Proc or report error
fn restart_app(proc: Proc) -> Result<Proc> {
let app = proc.app.clone();
let name = proc.app.name.clone();
match Proc::start(app) {
Ok(p) => Ok(p),
Err(e) => {
error!("error restarting {}", name);
error!("{:?}", e);
Err(e)
}
}
}
fn find_proc_by_token(token: Token, procs: &[Proc]) -> Option<usize> {
for (counter, proc) in procs.iter().enumerate() {
if proc.token == token {
return Some(counter);
}
}
None
}
fn process_event_data(channel: StdioChannel, data: String, app_name: &str) {
let c = match channel {
StdioChannel::Stdout => "stdout",
StdioChannel::Stderr => "stderr",
};
info!("[{}] {}: {}", c, app_name, data);
}
/// run the main loop until out of holds
fn run_loop(procs: Vec<Proc>, holds: Option<i8>, poll: Poll) -> Vec<Proc> {
let mut procs = procs;
let mut holds = holds;
let mut events = Events::with_capacity(1024);
while holds > Some(0) {
poll.poll(&mut events, None).unwrap();
for event in events.iter() {
if let Some(i) = find_proc_by_token(event.token(), &procs) {
let mut proc = procs.remove(i);
match proc.process.try_recv() {
Ok(ProcessEvent::Data(channel, data)) => {
process_event_data(channel, data, &proc.app.name);
procs.push(proc);
}
Ok(ProcessEvent::CommandError(e)) => {
error!("[{}]: command error: {:?}", &proc.app.name, e)
}
Ok(ProcessEvent::IoError(channel, e)) => {
error!("[{}]: io error on {:?}: {:?}", &proc.app.name, channel, e)
}
Ok(ProcessEvent::Utf8Error(channel, e)) => {
error!("[{}]: utf8 error on {:?}: {:?}", &proc.app.name, channel, e)
}
Ok(ProcessEvent::Exit(status)) => {
let hold = proc.app.hold.unwrap_or(false);
if proc.app.check_restart(status) {
if let Ok(p) = restart_app(proc) {
poll.register(&p.process, p.token, Ready::all(), PollOpt::edge())
.unwrap();
procs.push(p);
} else if hold {
holds = Some(holds.unwrap_or(0) - 1);
}
} else if hold {
holds = Some(holds.unwrap_or(0) - 1);
}
}
Err(TryRecvError::Empty) => {}
Err(TryRecvError::Disconnected) => {}
};
}
}
}
procs
}
Loading…
Cancel
Save