Added watchdog for hanging apps
This commit is contained in:
		| @@ -6,6 +6,9 @@ ScreenY = 40 | ||||
|  | ||||
| Serial = "/dev/ttyACM0" | ||||
|  | ||||
| # kills app after some seconds if it sends no data | ||||
| NoDataTimeout = 10 | ||||
|  | ||||
| # first app is always running in IDLE     | ||||
| Apps = [ | ||||
|     {"name": "pixelflut", "cmd": "apps/idle.py", "permanent": True}, | ||||
|   | ||||
							
								
								
									
										36
									
								
								main.py
									
									
									
									
									
								
							
							
						
						
									
										36
									
								
								main.py
									
									
									
									
									
								
							| @@ -16,7 +16,6 @@ class SerialWriter(threading.Thread): | ||||
|     def setData(self, data): | ||||
|         with self.lock: | ||||
|             self.data = data | ||||
|         pass | ||||
|      | ||||
|     def run(self): | ||||
|         should_connect = True | ||||
| @@ -38,6 +37,16 @@ class SerialWriter(threading.Thread): | ||||
|                 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): | ||||
| @@ -50,17 +59,32 @@ class AppRunner(threading.Thread): | ||||
|         self.param = "" | ||||
|         self.serial = SerialWriter() | ||||
|         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=""): | ||||
|         with self.lock: | ||||
|             self.requestedApp = app | ||||
|             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): | ||||
|         if self.app != None: | ||||
|             self.app.terminate() | ||||
|         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): | ||||
|         while True: | ||||
| @@ -73,8 +97,12 @@ class AppRunner(threading.Thread): | ||||
|                     self.requestedApp = None | ||||
|             d = self.app.stdout | ||||
|             oshandle = d.fileno() | ||||
|             data = os.read(oshandle, config.ScreenX*config.ScreenY*3) | ||||
|             self.serial.setData(data) | ||||
|             try: | ||||
|                 data = os.read(oshandle, config.ScreenX*config.ScreenY*3) | ||||
|                 self.last_update = time.time() | ||||
|                 self.serial.setData(data) | ||||
|             except: | ||||
|                 pass | ||||
|  | ||||
|  | ||||
| runner = AppRunner() | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 deckensteuerung
					deckensteuerung