Added watchdog for hanging apps
This commit is contained in:
parent
a11294d4f2
commit
629be93221
@ -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
32
main.py
@ -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()
|
||||||
|
Loading…
Reference in New Issue
Block a user