!7 sS iconID = /*#1101425*/#1101427; static double delay = 30.0, timeout = 30.0; static int consecutiveFailsThreshold = 3; // TODO: change if loading sS osBotName = "Stefan's OS."; sbool v6; static int consecutiveFails; static volatile S status; svoid activateOS { sendOpt("Stefan'S OS", "activate frames"); } p { bot("Stefan's OS Watch Dog."); installTrayIcon(iconID, "Stefan's OS Watch Dog", r activateOS, "Restart OS Now", r restartOSNow, "Show Watch Dog Window", r showConsole, "Hide Watch Dog Window", r hideConsole, "Exit Watch Dog", rThread cleanKill); consoleIcon(iconID); //printWithDateAndTimeInThisThread(); doEvery(delay, r { bool ok = false; pcall { long time = sysNow(); S s = evalWithTimeoutOrNull(timeout, func -> S { sendOpt(osBotName, "swing latency") }); if (isInteger(s)) { hideConsole(); ok = true; consecutiveFails = 0; printAndProgramLog(status = "Stefan's OS OK - Swing latency " + s + " ms, " + (sysNow()-time) + " ms"); //v6 = isProgramRunning(#1016478); v6 = sameSnippetID(#1016478, evalWithTimeoutOrNull(timeout, func -> S { send("Stefan's OS", "program id") })); } else showConsole(); consoleStatus(ok ? "OK" : "FAIL"); } if (!ok) { ++consecutiveFails; printAndProgramLog(status = "Stefan's OS fail #" + consecutiveFails + " of " + consecutiveFailsThreshold); pcall { osFailActivity(); } } }); hideConsole(); quickRestartOnSocketLoss(); sleep(); } svoid osFailActivity { if (consecutiveFails >= consecutiveFailsThreshold) restartOSNow(); } svoid restartOSNow { printAndProgramLog("RESTARTING STEFAN'S OS " + (v6 ? "v6" : "v5") + "."); consecutiveFails = 0; hardKillProgram(#1016005); hardKillProgram(#1016478); nohupJavax(v6 ? #1016478 : #1016005); } answer { if "status" ret status; } // TODO svoid quickRestartOnSocketLoss { /*int port = getVMPortForBot(osBotName); if (port != 0) talkTo(port);*/ }