Author: Pedro Lucas Porcellis <porcellis@eletrotupi.com>
beterrabad: boot services and check them periodically
cmd/beterrabad/main.ha | 81 +++++++++++++++++++++++++++++++++++++++++--
diff --git a/cmd/beterrabad/main.ha b/cmd/beterrabad/main.ha index 62d4b543a64d0c9a94b188bdda19846896a9bf67..68ff3d85dd3d3adc236712cd991e1122990215c1 100644 --- a/cmd/beterrabad/main.ha +++ b/cmd/beterrabad/main.ha @@ -1,5 +1,6 @@ use beterraba; use os; +use os::exec; use fs; use io; use strings; @@ -58,12 +59,84 @@ //const sock = bind(&services, sigfd); //defer shutdown(&sock); //for (dispatch(&sock)) void; + fmt::println("beterrabad service running")!; + + // Boot all services up for (let i = 0z; i < len(services); i += 1) { - fmt::printfln("\t {} - Cmd: {}", - services[i].name, services[i].cmd)!; + // TODO: Only start things up if we have any services at all, + // otherwise, bail out + boot(&services[i]); + }; + + // Keep checking them 'til you die + for (true) { + for (let i = 0z; i < len(services); i += 1) { + switch (services[i].status) { + case beterraba::status::STOPPED => + boot(&services[i]); + case beterraba::status::STARTED => + peek(&services[i]); + case beterraba::status::CRASHED => + recover(&services[i]); + }; + }; + }; + + fmt::println("beterrabad service shutdown")!; +}; + +// Check if the process is still alive and bail out if it's ok +fn peek(service: *beterraba::service) void = { + // TODO: Move this kind of thing into a better structured log facility + //fmt::printfln("Peeking on {}", service.name)!; + + match (exec::peek(&service.process)) { + case let s: exec::status => + let status = exec::exit(&s); + + match (status) { + case exec::exit_status => + service.status = beterraba::status::STOPPED; + case exec::signaled => + // TODO: Add the exit msg + service.status = beterraba::status::CRASHED; + }; + case void => + return; + case let err: exec::error => + service.status = beterraba::status::CRASHED; }; +}; - for (let i = 0z; i < len(services); i += 1) { - beterraba::finish(&services[i]); +// Try to recover a service which might have crashed +fn recover(service: *beterraba::service) void = { + fmt::printfln("Implement!")!; +}; + +fn boot(service: *beterraba::service) void = { + fmt::printfln("Booting up {}", service.name)!; + + let cmd = exec::cmd(service.definition.cmd, service.definition.args); + + match (cmd) { + case let cmddef: exec::command => + let proc = exec::start(&cmddef); + + // If there's a PID, the process is probably fine + match (proc) { + case let e: exec::error => + service.status = beterraba::status::CRASHED; + + case let p: exec::process => + service.status = beterraba::status::STARTED; + service.process = p; + }; + + case exec::nocmd => + fmt::printfln("Couldn't execute cmd {}", service.definition.cmd)!; + case exec::error => + fmt::printfln("Couldn't execute cmd {}, error", service.definition.cmd)!; + case => + fmt::println("Something went terrible wrong, good luck!")!; }; };