From 11e4c12f8549f133381995233c1301fd158f5cc5 Mon Sep 17 00:00:00 2001 From: misyaguziya Date: Thu, 26 Sep 2024 08:17:38 +0900 Subject: [PATCH 1/4] =?UTF-8?q?=F0=9F=91=8D=EF=B8=8F[Update]=20Model=20:?= =?UTF-8?q?=20Watchdog=E3=82=BF=E3=82=A4=E3=83=9E=E3=83=BC=E6=A9=9F?= =?UTF-8?q?=E8=83=BD=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "/run/feed_watchdog"でタイマーを定期的にリセットする必要あり --- src-python/config.py | 10 +++++++++ src-python/model.py | 11 ++++++++++ src-python/models/watchdog/watchdog.py | 30 ++++++++++++++++++++++++++ src-python/webui_controller.py | 19 +++++++++++++++- src-python/webui_mainloop.py | 6 +++++- 5 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 src-python/models/watchdog/watchdog.py diff --git a/src-python/config.py b/src-python/config.py index bc61ccd5..81d27b54 100644 --- a/src-python/config.py +++ b/src-python/config.py @@ -106,6 +106,14 @@ class Config: def MAX_SPEAKER_THRESHOLD(self): return self._MAX_SPEAKER_THRESHOLD + @property + def WATCHDOG_TIMEOUT(self): + return self._WATCHDOG_TIMEOUT + + @property + def WATCHDOG_INTERVAL(self): + return self._WATCHDOG_INTERVAL + # Read Write @property def ENABLE_SPEAKER2CHATBOX(self): @@ -992,6 +1000,8 @@ class Config: self._MAX_MIC_THRESHOLD = 2000 self._MAX_SPEAKER_THRESHOLD = 4000 + self._WATCHDOG_TIMEOUT = 30 + self._WATCHDOG_INTERVAL = 1 # Read Write self._ENABLE_TRANSLATION = False diff --git a/src-python/model.py b/src-python/model.py index 9c8ac248..4773d9d5 100644 --- a/src-python/model.py +++ b/src-python/model.py @@ -28,6 +28,7 @@ from models.translation.translation_utils import checkCTranslate2Weight, downloa from models.transcription.transcription_whisper import checkWhisperWeight, downloadWhisperWeight from models.overlay.overlay import Overlay from models.overlay.overlay_image import OverlayImage +from models.watchdog.watchdog import Watchdog from config import config @@ -101,6 +102,7 @@ class Model: self.mic_mute_status = None self.mic_mute_status_check = None self.kks = kakasi() + self.watchdog = Watchdog(config.WATCHDOG_TIMEOUT, config.WATCHDOG_INTERVAL) def checkCTranslatorCTranslate2ModelWeight(self): return checkCTranslate2Weight(config.PATH_LOCAL, config.CTRANSLATE2_WEIGHT_TYPE) @@ -780,4 +782,13 @@ class Model: def shutdownOverlay(self): self.overlay.shutdownOverlay() + def startWatchdog(self): + self.watchdog.start() + + def feedWatchdog(self): + self.watchdog.feed() + + def stopWatchdog(self): + self.watchdog.stop() + model = Model() \ No newline at end of file diff --git a/src-python/models/watchdog/watchdog.py b/src-python/models/watchdog/watchdog.py new file mode 100644 index 00000000..10b5b9e1 --- /dev/null +++ b/src-python/models/watchdog/watchdog.py @@ -0,0 +1,30 @@ +import os +import time +from threading import Thread, Event +from utils import printLog + +class Watchdog: + def __init__(self, timeout:int=60, interval:int=1): + self.timeout = timeout + self.interval = interval + self.last_feed_time = time.time() + self._stop_event = Event() + self._watchdog_thread = Thread(target=self._watchdog_loop) + + def start(self): + self._watchdog_thread.start() + + def stop(self): + self._stop_event.set() + self._watchdog_thread.join() + + def feed(self): + self.last_feed_time = time.time() + + def _watchdog_loop(self): + while not self._stop_event.is_set(): + if time.time() - self.last_feed_time > self.timeout: + printLog("Watchdog timeout! Shutting down...") + os._exit(1) + + time.sleep(self.interval) \ No newline at end of file diff --git a/src-python/webui_controller.py b/src-python/webui_controller.py index 49433bea..50c388a2 100644 --- a/src-python/webui_controller.py +++ b/src-python/webui_controller.py @@ -1527,6 +1527,21 @@ class Controller: th_download.daemon = True th_download.start() + @staticmethod + def startWatchdog() -> dict: + model.startWatchdog() + return {"status":200, "result":True} + + @staticmethod + def feedWatchdog() -> dict: + model.feedWatchdog() + return {"status":200, "result":True} + + @staticmethod + def stopWatchdog() -> dict: + model.stopWatchdog() + return {"status":200, "result":True} + def init(self, *args, **kwargs) -> None: printLog("Start Initialization") @@ -1591,4 +1606,6 @@ class Controller: device_manager.setCallbackMicDeviceList(self.updateMicDeviceList) device_manager.setCallbackSpeakerDeviceList(self.updateSpeakerDeviceList) - printLog("End Initialization") \ No newline at end of file + printLog("End Initialization") + + self.startWatchdog() \ No newline at end of file diff --git a/src-python/webui_mainloop.py b/src-python/webui_mainloop.py index 57da7aa2..800f4058 100644 --- a/src-python/webui_mainloop.py +++ b/src-python/webui_mainloop.py @@ -310,6 +310,10 @@ mapping = { # "/run/update_software": {"status": True, "variable":controller.updateSoftware}, # "/run/restart_software": {"status": True, "variable":controller.restartSoftware}, + + # "/run/start_watchdog": {"status": True, "variable":controller.startWatchdog}, + "/run/feed_watchdog": {"status": True, "variable":controller.feedWatchdog}, + # "/run/stop_watchdog": {"status": True, "variable":controller.stopWatchdog}, } class Main: @@ -333,7 +337,7 @@ class Main: th_receiver.daemon = True th_receiver.start() - def handleRequest(self, endpoint, data=None): + def handleRequest(self, endpoint, data=None) -> tuple: handler = mapping.get(endpoint) if handler is None: response = "Invalid endpoint" From 726dff60bd864fb1a33383838089801e9e9ea087 Mon Sep 17 00:00:00 2001 From: Sakamoto Shiina <68018796+ShiinaSakamoto@users.noreply.github.com> Date: Thu, 26 Sep 2024 12:31:50 +0900 Subject: [PATCH 2/4] =?UTF-8?q?[Update/bugfix]=20UI:=20Watchdog=E3=82=BF?= =?UTF-8?q?=E3=82=A4=E3=83=9E=E3=83=BC=E3=81=AB10=E7=A7=92=E9=96=93?= =?UTF-8?q?=E9=9A=94=E3=81=A7=E4=BF=A1=E5=8F=B7=E3=82=92=E9=80=81=E3=82=8B?= =?UTF-8?q?=E3=82=88=E3=81=86=E3=81=AB=E3=80=82=20backend=20watchdog?= =?UTF-8?q?=E9=96=A2=E6=95=B0=E3=81=AE=E5=BC=95=E6=95=B0=E3=82=A8=E3=83=A9?= =?UTF-8?q?=E3=83=BC=E3=81=AE=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src-python/webui_controller.py | 2 +- src-ui/app/App.jsx | 10 ++++++++++ src-ui/logics/useReceiveRoutes.js | 1 + 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src-python/webui_controller.py b/src-python/webui_controller.py index 50c388a2..109f533b 100644 --- a/src-python/webui_controller.py +++ b/src-python/webui_controller.py @@ -1533,7 +1533,7 @@ class Controller: return {"status":200, "result":True} @staticmethod - def feedWatchdog() -> dict: + def feedWatchdog(*args, **kwargs) -> dict: model.feedWatchdog() return {"status":200, "result":True} diff --git a/src-ui/app/App.jsx b/src-ui/app/App.jsx index 80809c7d..08eccea8 100644 --- a/src-ui/app/App.jsx +++ b/src-ui/app/App.jsx @@ -68,6 +68,8 @@ const StartPythonFacadeComponent = () => { main_page.setDecorations(true); if (!hasRunRef.current) { asyncStartPython().then((result) => { + startFeedingToWatchDog(); + getUiLanguage(); getIsMainPageCompactMode(); @@ -133,4 +135,12 @@ const ConfigPageCloseTrigger = () => { } }, [currentIsOpenedConfigPage]); return null; +}; + +import { useStdoutToPython } from "@logics/useStdoutToPython"; +const startFeedingToWatchDog = () => { + const { asyncStdoutToPython } = useStdoutToPython(); + setInterval(() => { + asyncStdoutToPython("/run/feed_watchdog"); + }, 10000); // 10000ミリ秒 = 10秒 }; \ No newline at end of file diff --git a/src-ui/logics/useReceiveRoutes.js b/src-ui/logics/useReceiveRoutes.js index 45bb2cbd..3e5a6014 100644 --- a/src-ui/logics/useReceiveRoutes.js +++ b/src-ui/logics/useReceiveRoutes.js @@ -68,6 +68,7 @@ export const useReceiveRoutes = () => { } = useVolume(); const routes = { + "/run/feed_watchdog": () => {}, // Main Page // Page Controls "/get/data/main_window_sidebar_compact_mode": updateIsMainPageCompactMode, From 71225bf045cc401d0338bebf71fcba7b615747e9 Mon Sep 17 00:00:00 2001 From: misyaguziya Date: Thu, 26 Sep 2024 12:50:00 +0900 Subject: [PATCH 3/4] =?UTF-8?q?=F0=9F=91=8D=EF=B8=8F[Update]=20Model=20:?= =?UTF-8?q?=20Watchdog=E3=81=AE=E5=BC=95=E6=95=B0(*args,=20**kwargs)?= =?UTF-8?q?=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src-python/webui_controller.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src-python/webui_controller.py b/src-python/webui_controller.py index 109f533b..23aa9a89 100644 --- a/src-python/webui_controller.py +++ b/src-python/webui_controller.py @@ -1528,7 +1528,7 @@ class Controller: th_download.start() @staticmethod - def startWatchdog() -> dict: + def startWatchdog(*args, **kwargs) -> dict: model.startWatchdog() return {"status":200, "result":True} @@ -1538,7 +1538,7 @@ class Controller: return {"status":200, "result":True} @staticmethod - def stopWatchdog() -> dict: + def stopWatchdog(*args, **kwargs) -> dict: model.stopWatchdog() return {"status":200, "result":True} From a0407afa540a572f1d08446a517129d77d8d4236 Mon Sep 17 00:00:00 2001 From: misyaguziya Date: Fri, 27 Sep 2024 01:02:20 +0900 Subject: [PATCH 4/4] =?UTF-8?q?=F0=9F=91=8D=EF=B8=8F[Update]=20Model=20:?= =?UTF-8?q?=20Watchdog=20timer=E3=81=AE=E7=B5=82=E4=BA=86=E5=87=A6?= =?UTF-8?q?=E7=90=86=E3=82=92main=20loop=E3=81=AE=E7=B5=82=E4=BA=86?= =?UTF-8?q?=E5=87=A6=E7=90=86=E3=81=AB=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src-python/config.py | 4 ++-- src-python/model.py | 12 +++++++++-- src-python/models/watchdog/watchdog.py | 28 +++++++++----------------- src-python/webui_controller.py | 4 ++++ src-python/webui_mainloop.py | 11 +++++++--- src-ui/app/App.jsx | 2 +- 6 files changed, 35 insertions(+), 26 deletions(-) diff --git a/src-python/config.py b/src-python/config.py index 81d27b54..44f3fa4e 100644 --- a/src-python/config.py +++ b/src-python/config.py @@ -1000,8 +1000,8 @@ class Config: self._MAX_MIC_THRESHOLD = 2000 self._MAX_SPEAKER_THRESHOLD = 4000 - self._WATCHDOG_TIMEOUT = 30 - self._WATCHDOG_INTERVAL = 1 + self._WATCHDOG_TIMEOUT = 60 + self._WATCHDOG_INTERVAL = 20 # Read Write self._ENABLE_TRANSLATION = False diff --git a/src-python/model.py b/src-python/model.py index 4773d9d5..8c465e7e 100644 --- a/src-python/model.py +++ b/src-python/model.py @@ -783,12 +783,20 @@ class Model: self.overlay.shutdownOverlay() def startWatchdog(self): - self.watchdog.start() + self.th_watchdog = threadFnc(self.watchdog.start) + self.th_watchdog.daemon = True + self.th_watchdog.start() def feedWatchdog(self): self.watchdog.feed() + def setWatchdogCallback(self, callback): + self.watchdog.setCallback(callback) + def stopWatchdog(self): - self.watchdog.stop() + if isinstance(self.th_watchdog, threadFnc): + self.th_watchdog.stop() + self.th_watchdog.join() + self.th_watchdog = None model = Model() \ No newline at end of file diff --git a/src-python/models/watchdog/watchdog.py b/src-python/models/watchdog/watchdog.py index 10b5b9e1..089e8680 100644 --- a/src-python/models/watchdog/watchdog.py +++ b/src-python/models/watchdog/watchdog.py @@ -1,30 +1,22 @@ -import os +from typing import Callable import time -from threading import Thread, Event from utils import printLog class Watchdog: - def __init__(self, timeout:int=60, interval:int=1): + def __init__(self, timeout:int=60, interval:int=20): self.timeout = timeout self.interval = interval self.last_feed_time = time.time() - self._stop_event = Event() - self._watchdog_thread = Thread(target=self._watchdog_loop) - - def start(self): - self._watchdog_thread.start() - - def stop(self): - self._stop_event.set() - self._watchdog_thread.join() def feed(self): self.last_feed_time = time.time() - def _watchdog_loop(self): - while not self._stop_event.is_set(): - if time.time() - self.last_feed_time > self.timeout: - printLog("Watchdog timeout! Shutting down...") - os._exit(1) + def setCallback(self, callback): + self.callback = callback - time.sleep(self.interval) \ No newline at end of file + def start(self): + if time.time() - self.last_feed_time > self.timeout: + printLog("Watchdog timeout! Shutting down...") + if isinstance(self.callback, Callable): + self.callback() + time.sleep(self.interval) \ No newline at end of file diff --git a/src-python/webui_controller.py b/src-python/webui_controller.py index 23aa9a89..82edcd0a 100644 --- a/src-python/webui_controller.py +++ b/src-python/webui_controller.py @@ -1537,6 +1537,10 @@ class Controller: model.feedWatchdog() return {"status":200, "result":True} + @staticmethod + def setWatchdogCallback(callback) -> dict: + model.setWatchdogCallback(callback) + @staticmethod def stopWatchdog(*args, **kwargs) -> dict: model.stopWatchdog() diff --git a/src-python/webui_mainloop.py b/src-python/webui_mainloop.py index 800f4058..2e6b8197 100644 --- a/src-python/webui_mainloop.py +++ b/src-python/webui_mainloop.py @@ -319,6 +319,7 @@ mapping = { class Main: def __init__(self) -> None: self.queue = Queue() + self.main_loop = True def receiver(self) -> None: while True: @@ -380,15 +381,19 @@ class Main: th_handler.daemon = True th_handler.start() - def loop(self) -> None: - while True: + def start(self) -> None: + while self.main_loop: time.sleep(1) + def stop(self) -> None: + self.main_loop = False + if __name__ == "__main__": main = Main() main.startReceiver() main.startHandler() + controller.setWatchdogCallback(main.stop) controller.init() # mappingのすべてのstatusをTrueにする @@ -398,7 +403,7 @@ if __name__ == "__main__": process = "main" match process: case "main": - main.loop() + main.start() case "test": for _ in range(100): diff --git a/src-ui/app/App.jsx b/src-ui/app/App.jsx index 08eccea8..5d04fc92 100644 --- a/src-ui/app/App.jsx +++ b/src-ui/app/App.jsx @@ -142,5 +142,5 @@ const startFeedingToWatchDog = () => { const { asyncStdoutToPython } = useStdoutToPython(); setInterval(() => { asyncStdoutToPython("/run/feed_watchdog"); - }, 10000); // 10000ミリ秒 = 10秒 + }, 20000); // 20000ミリ秒 = 20秒 }; \ No newline at end of file