beterraba

commit 8768aad4e9c9d3fd3442e737ab88c26fcb7b2c0c

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!")!;
 	};
 };