Added watchdog for hanging apps

This commit is contained in:
deckensteuerung 2018-08-22 18:48:43 +02:00
parent a11294d4f2
commit 629be93221
2 changed files with 35 additions and 4 deletions

View File

@ -6,6 +6,9 @@ ScreenY = 40
Serial = "/dev/ttyACM0" Serial = "/dev/ttyACM0"
# kills app after some seconds if it sends no data
NoDataTimeout = 10
# first app is always running in IDLE # first app is always running in IDLE
Apps = [ Apps = [
{"name": "pixelflut", "cmd": "apps/idle.py", "permanent": True}, {"name": "pixelflut", "cmd": "apps/idle.py", "permanent": True},

32
main.py
View File

@ -16,7 +16,6 @@ class SerialWriter(threading.Thread):
def setData(self, data): def setData(self, data):
with self.lock: with self.lock:
self.data = data self.data = data
pass
def run(self): def run(self):
should_connect = True should_connect = True
@ -38,6 +37,16 @@ class SerialWriter(threading.Thread):
time.sleep(0.1) time.sleep(0.1)
class WatchDog(threading.Thread):
def __init__(self, check, action):
super().__init__()
self.check = check
self.action = action
def run(self):
while True:
if self.check():
self.action()
time.sleep(1)
class AppRunner(threading.Thread): class AppRunner(threading.Thread):
@ -50,17 +59,32 @@ class AppRunner(threading.Thread):
self.param = "" self.param = ""
self.serial = SerialWriter() self.serial = SerialWriter()
self.serial.start() self.serial.start()
self.last_update = time.time()
self.watchdog = WatchDog(lambda: self.appTimedOut(), lambda: self.terminateApp())
self.watchdog.start()
def requestApp(self, app, param=""): def requestApp(self, app, param=""):
with self.lock: with self.lock:
self.requestedApp = app self.requestedApp = app
self.param = param self.param = param
def terminateApp(self):
if self.app != None:
# don't ask
self.app.terminate()
self.app.kill()
self.app.stdout.close()
self.last_update = time.time()
self.requestApp = 0
def appTimedOut(self):
return time.time()-self.last_update > config.NoDataTimeout
def updateApp(self): def updateApp(self):
if self.app != None: if self.app != None:
self.app.terminate() self.app.terminate()
args = [os.getcwd()+"/"+config.Apps[self.requestedApp]["cmd"], str(config.ScreenX), str(config.ScreenY), self.param] args = [os.getcwd()+"/"+config.Apps[self.requestedApp]["cmd"], str(config.ScreenX), str(config.ScreenY), self.param]
self.app = subprocess.Popen(args, stdout=subprocess.PIPE) self.app = subprocess.Popen(args, stdout=subprocess.PIPE, close_fds=True)
def run(self): def run(self):
while True: while True:
@ -73,8 +97,12 @@ class AppRunner(threading.Thread):
self.requestedApp = None self.requestedApp = None
d = self.app.stdout d = self.app.stdout
oshandle = d.fileno() oshandle = d.fileno()
try:
data = os.read(oshandle, config.ScreenX*config.ScreenY*3) data = os.read(oshandle, config.ScreenX*config.ScreenY*3)
self.last_update = time.time()
self.serial.setData(data) self.serial.setData(data)
except:
pass
runner = AppRunner() runner = AppRunner()