From 02c2edc30ecfc1dd09bef6808ead05332ef043bd Mon Sep 17 00:00:00 2001 From: jxxghp Date: Mon, 20 May 2024 11:50:49 +0800 Subject: [PATCH] =?UTF-8?q?fix=20WEB=E9=A1=B5=E9=9D=A2=E6=B4=BB=E5=8A=A8?= =?UTF-8?q?=E6=97=B6=E6=97=A0=E6=B3=95=E6=AD=A3=E5=B8=B8=E5=81=9C=E6=AD=A2?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/endpoints/system.py | 10 +++++++++- app/command.py | 2 ++ app/core/config.py | 28 ++++++++++++++++++++++++++++ app/core/module.py | 2 ++ app/core/plugin.py | 5 ++++- app/main.py | 22 +++++++++++++++++++++- app/scheduler.py | 2 ++ 7 files changed, 68 insertions(+), 3 deletions(-) diff --git a/app/api/endpoints/system.py b/app/api/endpoints/system.py index c3f3f84f..1fa011ba 100644 --- a/app/api/endpoints/system.py +++ b/app/api/endpoints/system.py @@ -11,7 +11,7 @@ from fastapi.responses import StreamingResponse from app import schemas from app.chain.search import SearchChain from app.chain.system import SystemChain -from app.core.config import settings +from app.core.config import settings, global_vars from app.core.module import ModuleManager from app.core.security import verify_token from app.db.models import User @@ -99,6 +99,8 @@ def get_progress(process_type: str, token: str): def event_generator(): while True: + if global_vars.is_system_stopped(): + break detail = progress.get(process_type) yield 'data: %s\n\n' % json.dumps(detail) time.sleep(0.2) @@ -156,6 +158,8 @@ def get_message(token: str, role: str = "sys"): def event_generator(): while True: + if global_vars.is_system_stopped(): + break detail = message.get(role) yield 'data: %s\n\n' % (detail or '') time.sleep(3) @@ -184,6 +188,8 @@ def get_logging(token: str, length: int = 50, logfile: str = "moviepilot.log"): for line in f.readlines()[-max(length, 50):]: yield 'data: %s\n\n' % line while True: + if global_vars.is_system_stopped(): + break for t in tailer.follow(open(log_path, 'r', encoding='utf-8')): yield 'data: %s\n\n' % (t or '') time.sleep(1) @@ -305,6 +311,8 @@ def restart_system(_: User = Depends(get_current_active_superuser)): """ if not SystemUtils.can_restart(): return schemas.Response(success=False, message="当前运行环境不支持重启操作!") + # 标识停止事件 + global_vars.stop_system() # 执行重启 ret, msg = SystemUtils.restart() return schemas.Response(success=ret, message=msg) diff --git a/app/command.py b/app/command.py index 890ab53a..72bad0f8 100644 --- a/app/command.py +++ b/app/command.py @@ -279,9 +279,11 @@ class Command(metaclass=Singleton): """ 停止事件处理线程 """ + logger.info("正在停止事件处理...") self._event.set() try: self._thread.join() + logger.info("事件处理停止完成") except Exception as e: logger.error(f"停止事件处理线程出错:{str(e)} - {traceback.format_exc()}") diff --git a/app/core/config.py b/app/core/config.py index 222c4cc0..114bee68 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -1,5 +1,6 @@ import secrets import sys +import threading from pathlib import Path from typing import List, Optional @@ -9,6 +10,9 @@ from app.utils.system import SystemUtils class Settings(BaseSettings): + """ + 系统配置类 + """ # 项目名称 PROJECT_NAME = "MoviePilot" # API路径 @@ -425,7 +429,31 @@ class Settings(BaseSettings): case_sensitive = True +class GlobalVar(object): + """ + 全局标识 + """ + # 系统停止事件 + STOP_EVENT: threading.Event = threading.Event() + + def stop_system(self): + """ + 停止系统 + """ + self.STOP_EVENT.set() + + def is_system_stopped(self): + """ + 是否停止 + """ + return self.STOP_EVENT.is_set() + + +# 实例化配置 settings = Settings( _env_file=Settings().CONFIG_PATH / "app.env", _env_file_encoding="utf-8" ) + +# 全局标识 +global_vars = GlobalVar() diff --git a/app/core/module.py b/app/core/module.py index 01df398f..bb397e53 100644 --- a/app/core/module.py +++ b/app/core/module.py @@ -51,6 +51,7 @@ class ModuleManager(metaclass=Singleton): """ 停止所有模块 """ + logger.info("正在停止所有模块...") for module_id, module in self._running_modules.items(): if hasattr(module, "stop"): try: @@ -58,6 +59,7 @@ class ModuleManager(metaclass=Singleton): logger.info(f"Moudle Stoped:{module_id}") except Exception as err: logger.error(f"Stop Moudle Error:{module_id},{str(err)} - {traceback.format_exc()}", exc_info=True) + logger.info("模块停止完成") def reload(self): """ diff --git a/app/core/plugin.py b/app/core/plugin.py index 035cce77..6891fc23 100644 --- a/app/core/plugin.py +++ b/app/core/plugin.py @@ -187,6 +187,7 @@ class PluginManager(metaclass=Singleton): :param pid: 插件ID,为空停止所有插件 """ # 停止插件 + logger.info("正在停止所有插件...") for plugin_id, plugin in self._running_plugins.items(): if pid and plugin_id != pid: continue @@ -202,6 +203,7 @@ class PluginManager(metaclass=Singleton): # 清空 self._plugins = {} self._running_plugins = {} + logger.info("插件停止完成") def __start_monitor(self): """ @@ -219,9 +221,10 @@ class PluginManager(metaclass=Singleton): """ # 停止监测 if self._observer: - logger.info("正在停止监测插件文件修改...") + logger.info("正在停止插件文件修改监测...") self._observer.stop() self._observer.join() + logger.info("插件文件修改监测停止完成") @staticmethod def __stop_plugin(plugin: Any): diff --git a/app/main.py b/app/main.py index fd33d9f1..f66fc1c3 100644 --- a/app/main.py +++ b/app/main.py @@ -1,7 +1,9 @@ import multiprocessing import os +import signal import sys import threading +from types import FrameType import uvicorn as uvicorn from PIL import Image @@ -16,7 +18,7 @@ if SystemUtils.is_frozen(): sys.stdout = open(os.devnull, 'w') sys.stderr = open(os.devnull, 'w') -from app.core.config import settings +from app.core.config import settings, global_vars from app.core.module import ModuleManager from app.core.plugin import PluginManager from app.db.init import init_db, update_db, init_super_user @@ -159,6 +161,22 @@ def check_auth(): ) +def singal_handle(): + """ + 监听停止信号 + """ + def stop_event(signum: int, _: FrameType): + """ + SIGTERM信号处理 + """ + print(f"接收到停止信号:{signum},正在停止系统...") + global_vars.stop_system() + + # 设置信号处理程序 + signal.signal(signal.SIGTERM, stop_event) + signal.signal(signal.SIGINT, stop_event) + + @App.on_event("shutdown") def shutdown_server(): """ @@ -210,6 +228,8 @@ def start_module(): start_frontend() # 检查认证状态 check_auth() + # 监听停止信号 + singal_handle() if __name__ == '__main__': diff --git a/app/scheduler.py b/app/scheduler.py index c4824857..77580f56 100644 --- a/app/scheduler.py +++ b/app/scheduler.py @@ -504,10 +504,12 @@ class Scheduler(metaclass=Singleton): """ try: if self._scheduler: + logger.info("正在停止定时任务...") self._event.set() self._scheduler.remove_all_jobs() if self._scheduler.running: self._scheduler.shutdown() self._scheduler = None + logger.info("定时任务停止完成") except Exception as e: logger.error(f"停止定时任务失败::{str(e)} - {traceback.format_exc()}")