68 lines
2.0 KiB
Python
68 lines
2.0 KiB
Python
from time import time, sleep
|
|
from typing import List
|
|
|
|
from biopro.message.request import DataMessageHandler
|
|
from biopro.util.console import BLUE
|
|
from .controller import ControlServerAPI
|
|
from .socket import ServerThread, ServerThreadClosedInterrupt
|
|
|
|
|
|
class DataStreamThread(ServerThread):
|
|
def __init__(self, server: ControlServerAPI):
|
|
super().__init__('DataStream', BLUE)
|
|
|
|
self._server = server
|
|
self._handle: List[DataMessageHandler] = []
|
|
|
|
def add_handle(self, handle: DataMessageHandler):
|
|
try:
|
|
self._handle.index(handle)
|
|
except ValueError:
|
|
self.log_verbose('add_handle', handle)
|
|
self._handle.append(handle)
|
|
|
|
def del_handle(self, handle: DataMessageHandler):
|
|
try:
|
|
self._handle.remove(handle)
|
|
self.log_verbose('del_handle', handle)
|
|
except ValueError:
|
|
pass
|
|
|
|
def has_handle(self) -> bool:
|
|
return len(self._handle) > 0
|
|
|
|
def shutdown(self) -> None:
|
|
self._handle.clear()
|
|
|
|
super().shutdown()
|
|
|
|
def routine(self, event = None) -> None:
|
|
t = time()
|
|
|
|
if len(self._handle) == 0:
|
|
event.wait(1)
|
|
|
|
else:
|
|
self._routine()
|
|
|
|
sleep_time = 1 - (time() - t)
|
|
|
|
if t > 0 and sleep_time > 0:
|
|
event.wait(sleep_time)
|
|
|
|
def _routine(self):
|
|
for h in list(self._handle):
|
|
if self.is_closed:
|
|
raise ServerThreadClosedInterrupt()
|
|
|
|
self._routine_handle(h)
|
|
|
|
def _routine_handle(self, handle: DataMessageHandler):
|
|
try:
|
|
self._server.websocket_data_request(handle, None)
|
|
except:
|
|
# in general, error cause by data message building will caught by try-except in websocket_data_request
|
|
# but if error cause from handler, such as disconnected, error will be raised to here,
|
|
# and we cannot rescue it, just remote this handle.
|
|
self.del_handle(handle)
|