from libs.app.common.logging import get_logger from flask import Flask, render_template, request from flask_socketio import SocketIO import multiprocessing import threading import time logger = get_logger() class UIServer: def __init__(self, host="127.0.0.1", port=5000): self.host = host self.port = port self.process = None self.queue = multiprocessing.Queue() self.client_ready = multiprocessing.Value("b", False) @staticmethod def run_server(host, port, queue, client_ready): app = Flask(__name__) socketio = SocketIO(app, cors_allowed_origins="*") @app.route("/") def index(): return render_template("index.html") @socketio.on("frontend_ready") def frontend_ready(): client_ready.value = True def queue_listener(): while True: event, data = queue.get() while not client_ready.value: time.sleep(1) socketio.emit(event, data) threading.Thread(target=queue_listener, daemon=True).start() socketio.run(app, host=host, port=port, debug=False, use_reloader=False) def start(self): if self.process and self.process.is_alive(): logger.debug("Server is already running") return self.process = multiprocessing.Process( target=UIServer.run_server, args=(self.host, self.port, self.queue, self.client_ready), ) self.process.start() logger.debug(f"Server started on http://{self.host}:{self.port}") def stop(self, wait_queue=True, time_limit=5): while wait_queue and not self.queue.empty(): logger.debug(f"Waiting server. {self.queue.qsize()} items in queue") time.sleep(1) time_limit-=1 if time_limit <= 0: break if self.process and self.process.is_alive(): self.process.terminate() self.process.join() logger.debug("Server stopped") self.process = None def restart(self): logger.debug("Restarting server...") self.stop() self.start() def emit_event(self, event, data={}): self.queue.put((event, data))