From 2fa40dac3ff5152750439385b9abae6f907e9d5d Mon Sep 17 00:00:00 2001 From: jxxghp Date: Wed, 20 Aug 2025 13:35:24 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E7=9B=91=E6=8E=A7=E5=92=8C?= =?UTF-8?q?=E6=B6=88=E6=81=AF=E6=9C=8D=E5=8A=A1=E7=9A=84=E8=B5=84=E6=BA=90?= =?UTF-8?q?=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/core/cache.py | 8 ++-- app/helper/message.py | 20 +++++++++- app/helper/redis.py | 3 +- app/modules/postgresql/__init__.py | 62 ++++++++++++++++++++++++++++++ app/modules/redis/__init__.py | 59 ++++++++++++++++++++++++++++ app/monitor.py | 4 +- app/schemas/types.py | 32 ++++++++------- app/startup/modules_initializer.py | 4 +- 8 files changed, 169 insertions(+), 23 deletions(-) diff --git a/app/core/cache.py b/app/core/cache.py index 737a74a6..5cb208ba 100644 --- a/app/core/cache.py +++ b/app/core/cache.py @@ -442,6 +442,10 @@ class TTLCache: logger.warning(f"缓存关闭失败: {e}") +# 缓存后端实例 +cache_backend = get_cache_backend() + + def cached(region: Optional[str] = None, maxsize: Optional[int] = 512, ttl: Optional[int] = 1800, skip_none: Optional[bool] = True, skip_empty: Optional[bool] = False): """ @@ -552,10 +556,6 @@ def cached(region: Optional[str] = None, maxsize: Optional[int] = 512, ttl: Opti return decorator -# 缓存后端实例 -cache_backend = get_cache_backend() - - def close_cache() -> None: """ 关闭缓存后端连接并清理资源 diff --git a/app/helper/message.py b/app/helper/message.py index e4364713..025de06c 100644 --- a/app/helper/message.py +++ b/app/helper/message.py @@ -10,9 +10,9 @@ from datetime import datetime from typing import Any, Literal, Optional, List, Dict, Union from typing import Callable -from app.core.cache import TTLCache from jinja2 import Template +from app.core.cache import TTLCache from app.core.config import global_vars from app.core.context import MediaInfo, TorrentInfo from app.core.meta import MetaBase @@ -471,6 +471,13 @@ class TemplateHelper(metaclass=SingletonClass): except json.JSONDecodeError: return rendered + def close(self): + """ + 清理资源 + """ + if self.cache: + self.cache.close() + class MessageTemplateHelper: """ @@ -704,6 +711,7 @@ class MessageQueueManager(metaclass=SingletonClass): 停止队列管理器 """ self._running = False + logger.info("正在停止消息队列...") self.thread.join() @@ -765,3 +773,13 @@ class MessageHelper(metaclass=Singleton): if not self.user_queue.empty(): return self.user_queue.get(block=False) return None + + +def stop_message(): + """ + 停止消息服务 + """ + # 停止消息队列 + MessageQueueManager().stop() + # 关闭消息演染器 + TemplateHelper().close() diff --git a/app/helper/redis.py b/app/helper/redis.py index 24c8e60e..35ca7363 100644 --- a/app/helper/redis.py +++ b/app/helper/redis.py @@ -10,10 +10,9 @@ from app.core.event import eventmanager, Event from app.log import logger from app.schemas import ConfigChangeEventData from app.schemas.types import EventType -from app.utils.singleton import Singleton -class RedisHelper(metaclass=Singleton): +class RedisHelper: """ Redis连接和操作助手类 diff --git a/app/modules/postgresql/__init__.py b/app/modules/postgresql/__init__.py index e69de29b..cc2a28a5 100644 --- a/app/modules/postgresql/__init__.py +++ b/app/modules/postgresql/__init__.py @@ -0,0 +1,62 @@ +from typing import Tuple, Union + +from app.core.config import settings +from app.db import SessionFactory +from app.modules import _ModuleBase +from app.schemas.types import ModuleType, OtherModulesType + + +class PostgreSQLModule(_ModuleBase): + """ + PostgreSQL 数据库模块 + """ + + def init_module(self) -> None: + pass + + @staticmethod + def get_name() -> str: + return "PostgreSQL" + + @staticmethod + def get_type() -> ModuleType: + """ + 获取模块类型 + """ + return ModuleType.Other + + @staticmethod + def get_subtype() -> OtherModulesType: + """ + 获取模块子类型 + """ + return OtherModulesType.PostgreSQL + + @staticmethod + def get_priority() -> int: + """ + 获取模块优先级,数字越小优先级越高,只有同一接口下优先级才生效 + """ + return 0 + + def init_setting(self) -> Tuple[str, Union[str, bool]]: + pass + + def stop(self) -> None: + pass + + def test(self): + """ + 测试模块连接性 + """ + if settings.DB_TYPE != "postgresql": + return None + # 测试数据库连接 + db = SessionFactory() + try: + db.execute("SELECT 1") + except Exception as e: + return False, f"PostgreSQL连接失败:{e}" + finally: + db.close() + return True, "" diff --git a/app/modules/redis/__init__.py b/app/modules/redis/__init__.py index e69de29b..54fb399a 100644 --- a/app/modules/redis/__init__.py +++ b/app/modules/redis/__init__.py @@ -0,0 +1,59 @@ +from typing import Tuple, Union + +from app.core.config import settings +from app.helper.redis import RedisHelper +from app.modules import _ModuleBase +from app.schemas.types import ModuleType, OtherModulesType + + +class RedisModule(_ModuleBase): + """ + Redis 数据库模块 + """ + + def init_module(self) -> None: + pass + + @staticmethod + def get_name() -> str: + return "Redis缓存" + + @staticmethod + def get_type() -> ModuleType: + """ + 获取模块类型 + """ + return ModuleType.Other + + @staticmethod + def get_subtype() -> OtherModulesType: + """ + 获取模块子类型 + """ + return OtherModulesType.Redis + + @staticmethod + def get_priority() -> int: + """ + 获取模块优先级,数字越小优先级越高,只有同一接口下优先级才生效 + """ + return 0 + + def init_setting(self) -> Tuple[str, Union[str, bool]]: + pass + + def stop(self) -> None: + pass + + def test(self): + """ + 测试模块连接性 + """ + if settings.CACHE_BACKEND_TYPE != "redis": + return None + try: + redis_helper = RedisHelper(redis_url=settings.CACHE_BACKEND_URL) + redis_helper.close() + except RuntimeError as e: + return False, f"Redis连接失败:{e}" + return True, "" diff --git a/app/monitor.py b/app/monitor.py index 1d098de6..8dfb3273 100644 --- a/app/monitor.py +++ b/app/monitor.py @@ -768,7 +768,7 @@ class Monitor(metaclass=Singleton): def stop(self): """ - 退出插件 + 退出监控 """ self._event.set() if self._observers: @@ -791,4 +791,6 @@ class Monitor(metaclass=Singleton): except Exception as e: logger.error(f"停止定时服务出现了错误:{e}") self._scheduler = None + if self._cache: + self._cache.close() self._event.clear() diff --git a/app/schemas/types.py b/app/schemas/types.py index e30e7e68..121c9d37 100644 --- a/app/schemas/types.py +++ b/app/schemas/types.py @@ -294,20 +294,6 @@ class MediaRecognizeType(Enum): Bangumi = "Bangumi" -# 其他杂项模块类型 -class OtherModulesType(Enum): - # 字幕 - Subtitle = "站点字幕" - # Fanart - Fanart = "Fanart" - # 文件整理 - FileManager = "文件整理" - # 过滤器 - Filter = "过滤器" - # 站点索引 - Indexer = "站点索引" - - # 用户配置Key字典 class UserConfigKey(Enum): # 监控面板 @@ -339,3 +325,21 @@ class ModuleType(Enum): Indexer = "indexer" # 其它 Other = "other" + + +# 其他杂项模块类型 +class OtherModulesType(Enum): + # 字幕 + Subtitle = "站点字幕" + # Fanart + Fanart = "Fanart" + # 文件整理 + FileManager = "文件整理" + # 过滤器 + Filter = "过滤器" + # 站点索引 + Indexer = "站点索引" + # PostgreSQL + PostgreSQL = "PostgreSQL" + # Redis + Redis = "Redis" diff --git a/app/startup/modules_initializer.py b/app/startup/modules_initializer.py index 42e742a5..98634628 100644 --- a/app/startup/modules_initializer.py +++ b/app/startup/modules_initializer.py @@ -19,7 +19,7 @@ from app.helper.thread import ThreadHelper from app.helper.display import DisplayHelper from app.helper.doh import DohHelper from app.helper.resource import ResourceHelper -from app.helper.message import MessageHelper +from app.helper.message import MessageHelper, stop_message from app.helper.subscribe import SubscribeHelper from app.db import close_database from app.db.systemconfig_oper import SystemConfigOper @@ -117,6 +117,8 @@ async def stop_modules(): DisplayHelper().stop() # 停止线程池 ThreadHelper().shutdown() + # 停止消息服务 + stop_message() # 停止缓存连接 close_cache() # 停止数据库连接