feat(config): 优化配置变更事件处理机制

This commit is contained in:
Attente
2025-11-27 23:17:34 +08:00
parent d1d7b8ce55
commit ca5ec8af0f
23 changed files with 205 additions and 335 deletions

View File

@@ -14,10 +14,8 @@ from threading import Lock
from typing import Dict, Optional
from app.core.config import settings
from app.core.event import Event, eventmanager
from app.log import logger
from app.schemas import ConfigChangeEventData
from app.schemas.types import EventType
from app.utils.mixins import ConfigReloadMixin
from app.utils.singleton import Singleton
# 定义一个全局线程池执行器
@@ -69,25 +67,23 @@ def enable_doh(enable: bool):
socket.getaddrinfo = _orig_getaddrinfo
class DohHelper(metaclass=Singleton):
class DohHelper(ConfigReloadMixin, metaclass=Singleton):
"""
DoH帮助类用于处理DNS over HTTPS解析。
"""
CONFIG_WATCH = {"DOH_ENABLE", "DOH_DOMAINS", "DOH_RESOLVERS"}
def __init__(self):
enable_doh(settings.DOH_ENABLE)
@eventmanager.register(EventType.ConfigChanged)
def handle_config_changed(self, event: Event):
if not event:
return
event_data: ConfigChangeEventData = event.event_data
if event_data.key not in ["DOH_ENABLE", "DOH_DOMAINS", "DOH_RESOLVERS"]:
return
def on_config_changed(self):
with _doh_lock:
# DOH配置有变动的情况下清空缓存
_doh_cache.clear()
enable_doh(settings.DOH_ENABLE)
def get_reload_name(self):
return 'DoH'
def _doh_query(resolver: str, host: str) -> Optional[str]:
"""

View File

@@ -7,10 +7,8 @@ import redis
from redis.asyncio import Redis
from app.core.config import settings
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.mixins import ConfigReloadMixin
from app.utils.singleton import Singleton
# 类型缓存集合,针对非容器简单类型
@@ -74,16 +72,17 @@ def deserialize(value: bytes) -> Any:
raise ValueError("Unknown serialization format")
class RedisHelper(metaclass=Singleton):
class RedisHelper(ConfigReloadMixin, metaclass=Singleton):
"""
Redis连接和操作助手类单例模式
特性:
- 管理Redis连接池和客户端
- 提供序列化和反序列化功能
- 支持内存限制和淘汰策略设置
- 提供键名生成和区域管理功能
"""
CONFIG_WATCH = {"CACHE_BACKEND_TYPE", "CACHE_BACKEND_URL", "CACHE_REDIS_MAXMEMORY"}
def __init__(self):
"""
@@ -114,25 +113,17 @@ class RedisHelper(metaclass=Singleton):
self.client = None
raise RuntimeError("Redis connection failed") from e
@eventmanager.register(EventType.ConfigChanged)
def handle_config_changed(self, event: Event):
"""
处理配置变更事件更新Redis设置
:param event: 事件对象
"""
if not event:
return
event_data: ConfigChangeEventData = event.event_data
if event_data.key not in ['CACHE_BACKEND_TYPE', 'CACHE_BACKEND_URL', 'CACHE_REDIS_MAXMEMORY']:
return
logger.info("配置变更重连Redis...")
def on_config_changed(self):
self.close()
self._connect()
def get_reload_name(self):
return "Redis"
def set_memory_limit(self, policy: Optional[str] = "allkeys-lru"):
"""
动态设置Redis最大内存和内存淘汰策略
:param policy: 淘汰策略(如'allkeys-lru'
"""
try:
@@ -310,10 +301,10 @@ class RedisHelper(metaclass=Singleton):
logger.debug("Redis connection closed")
class AsyncRedisHelper(metaclass=Singleton):
class AsyncRedisHelper(ConfigReloadMixin, metaclass=Singleton):
"""
异步Redis连接和操作助手类单例模式
特性:
- 管理异步Redis连接池和客户端
- 提供序列化和反序列化功能
@@ -321,6 +312,7 @@ class AsyncRedisHelper(metaclass=Singleton):
- 提供键名生成和区域管理功能
- 所有操作都是异步的
"""
CONFIG_WATCH = {"CACHE_BACKEND_TYPE", "CACHE_BACKEND_URL", "CACHE_REDIS_MAXMEMORY"}
def __init__(self):
"""
@@ -351,25 +343,17 @@ class AsyncRedisHelper(metaclass=Singleton):
self.client = None
raise RuntimeError("Redis async connection failed") from e
@eventmanager.register(EventType.ConfigChanged)
async def handle_config_changed(self, event: Event):
"""
处理配置变更事件更新Redis设置
:param event: 事件对象
"""
if not event:
return
event_data: ConfigChangeEventData = event.event_data
if event_data.key not in ['CACHE_BACKEND_TYPE', 'CACHE_BACKEND_URL', 'CACHE_REDIS_MAXMEMORY']:
return
logger.info("配置变更重连Redis (async)...")
async def on_config_changed(self):
await self.close()
await self._connect()
def get_reload_name(self):
return "Redis (async)"
async def set_memory_limit(self, policy: Optional[str] = "allkeys-lru"):
"""
动态设置Redis最大内存和内存淘汰策略
:param policy: 淘汰策略(如'allkeys-lru'
"""
try:

View File

@@ -8,35 +8,32 @@ from typing import Tuple
import docker
from app.core.config import settings
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.mixins import ConfigReloadMixin
from app.utils.system import SystemUtils
class SystemHelper:
class SystemHelper(ConfigReloadMixin):
"""
系统工具类,提供系统相关的操作和判断
"""
CONFIG_WATCH = {
"DEBUG",
"LOG_LEVEL",
"LOG_MAX_FILE_SIZE",
"LOG_BACKUP_COUNT",
"LOG_FILE_FORMAT",
"LOG_CONSOLE_FORMAT",
}
__system_flag_file = "/var/log/nginx/__moviepilot__"
@eventmanager.register(EventType.ConfigChanged)
def handle_config_changed(self, event: Event):
"""
处理配置变更事件,更新日志设置
:param event: 事件对象
"""
if not event:
return
event_data: ConfigChangeEventData = event.event_data
if event_data.key not in ['DEBUG', 'LOG_LEVEL', 'LOG_MAX_FILE_SIZE', 'LOG_BACKUP_COUNT',
'LOG_FILE_FORMAT', 'LOG_CONSOLE_FORMAT']:
return
logger.info("配置变更,更新日志设置...")
def on_config_changed(self):
logger.update_loggers()
def get_reload_name(self):
return "日志设置"
@staticmethod
def can_restart() -> bool:
"""