202 lines
6.0 KiB
Python
202 lines
6.0 KiB
Python
from contextlib import asynccontextmanager
|
|
from typing import Any
|
|
|
|
from cli.exit_codes import REDIS_ERROR, RUNTIME_ERROR
|
|
|
|
from .gateway import CacheInfrastructureGateway
|
|
|
|
|
|
class CacheDomainSupport:
|
|
"""
|
|
缓存领域支持对象。
|
|
|
|
该对象负责缓存名称列表构建、键范围解析和 TTL 结果判定等
|
|
局部缓存规则,避免主运行时服务继续承载细碎领域判断。
|
|
|
|
:param infrastructure_gateway: 缓存基础设施网关
|
|
"""
|
|
|
|
def __init__(self, infrastructure_gateway: CacheInfrastructureGateway) -> None:
|
|
"""
|
|
初始化缓存领域支持对象。
|
|
|
|
:param infrastructure_gateway: 缓存基础设施网关
|
|
:return: None
|
|
"""
|
|
self.infrastructure_gateway = infrastructure_gateway
|
|
|
|
def build_cache_name_items(self) -> list[dict[str, Any]]:
|
|
"""
|
|
构建系统内置缓存名称列表。
|
|
|
|
:return: 缓存名称列表
|
|
"""
|
|
redis_init_key_config = self.infrastructure_gateway.get_redis_init_key_config()
|
|
return [
|
|
{
|
|
'cacheName': key_config.key,
|
|
'remark': key_config.remark,
|
|
}
|
|
for key_config in redis_init_key_config
|
|
]
|
|
|
|
@staticmethod
|
|
def build_full_cache_key(cache_name: str, cache_key: str) -> str:
|
|
"""
|
|
构建缓存完整键名。
|
|
|
|
:param cache_name: 缓存名称
|
|
:param cache_key: 缓存键名
|
|
:return: 完整缓存键名
|
|
"""
|
|
return f'{cache_name}:{cache_key}'
|
|
|
|
def build_missing_cache_result(self, cache_name: str, cache_key: str) -> dict[str, Any]:
|
|
"""
|
|
构建缓存不存在的统一结果。
|
|
|
|
:param cache_name: 缓存名称
|
|
:param cache_key: 缓存键名
|
|
:return: 缓存不存在结果
|
|
"""
|
|
full_cache_key = self.build_full_cache_key(cache_name, cache_key)
|
|
return {
|
|
'ok': False,
|
|
'message': f'缓存不存在:{full_cache_key}',
|
|
'cacheName': cache_name,
|
|
'cacheKey': cache_key,
|
|
'fullCacheKey': full_cache_key,
|
|
'exit_code': RUNTIME_ERROR,
|
|
}
|
|
|
|
@staticmethod
|
|
def build_cache_name_pattern(cache_name: str) -> str:
|
|
"""
|
|
构建按缓存名称扫描时使用的 Redis 键模式。
|
|
|
|
:param cache_name: 缓存名称
|
|
:return: Redis 键匹配模式
|
|
"""
|
|
return f'{cache_name}:*'
|
|
|
|
@staticmethod
|
|
def extract_cache_key_items(cache_name: str, cache_keys: list[str]) -> list[str]:
|
|
"""
|
|
从缓存完整键名列表中提取相对键名。
|
|
|
|
:param cache_name: 缓存名称
|
|
:param cache_keys: 完整缓存键名列表
|
|
:return: 相对键名列表
|
|
"""
|
|
return [key.split(':', 1)[1] for key in sorted(cache_keys) if key.startswith(f'{cache_name}:')]
|
|
|
|
@staticmethod
|
|
def build_clear_scope(
|
|
*,
|
|
cache_name: str,
|
|
cache_key: str,
|
|
clear_all: bool,
|
|
) -> dict[str, str]:
|
|
"""
|
|
构建缓存清理范围定义。
|
|
|
|
:param cache_name: 缓存名称
|
|
:param cache_key: 缓存键名片段
|
|
:param clear_all: 是否清理全部缓存
|
|
:return: 清理范围定义
|
|
"""
|
|
if clear_all:
|
|
return {'mode': 'all'}
|
|
if cache_name:
|
|
return {'mode': 'cacheName', 'cacheName': cache_name}
|
|
return {'mode': 'cacheKey', 'cacheKey': cache_key}
|
|
|
|
|
|
class CacheRedisSupport:
|
|
"""
|
|
缓存 Redis 访问支持对象。
|
|
|
|
该对象负责 Redis 连接生命周期、错误结果规整和缓存键模式拼装,
|
|
避免主运行时服务继续承载基础设施桥接细节。
|
|
|
|
:param infrastructure_gateway: 缓存基础设施网关
|
|
:param domain_support: 缓存领域支持对象
|
|
"""
|
|
|
|
def __init__(
|
|
self,
|
|
infrastructure_gateway: CacheInfrastructureGateway,
|
|
domain_support: CacheDomainSupport,
|
|
) -> None:
|
|
"""
|
|
初始化缓存 Redis 访问支持对象。
|
|
|
|
:param infrastructure_gateway: 缓存基础设施网关
|
|
:param domain_support: 缓存领域支持对象
|
|
:return: None
|
|
"""
|
|
self.infrastructure_gateway = infrastructure_gateway
|
|
self.domain_support = domain_support
|
|
|
|
@asynccontextmanager
|
|
async def redis_session(self) -> Any:
|
|
"""
|
|
创建并托管 Redis 会话。
|
|
|
|
:return: `(redis, redis_util)` 元组
|
|
"""
|
|
redis = None
|
|
redis_util = self.infrastructure_gateway.get_redis_util()
|
|
try:
|
|
redis = await redis_util.create_redis_pool(log_enabled=False)
|
|
yield redis, redis_util
|
|
finally:
|
|
if redis is not None:
|
|
await redis.close()
|
|
|
|
@staticmethod
|
|
def build_redis_error_result(message: str, exc: Exception) -> dict[str, Any]:
|
|
"""
|
|
构建统一 Redis 异常结果。
|
|
|
|
:param message: 失败消息
|
|
:param exc: 原始异常
|
|
:return: 标准失败结果
|
|
"""
|
|
return {
|
|
'ok': False,
|
|
'message': message,
|
|
'error': str(exc),
|
|
'exit_code': REDIS_ERROR,
|
|
}
|
|
|
|
def build_cache_name_keys_pattern(self, cache_name: str) -> str:
|
|
"""
|
|
构建按缓存名称读取键列表时使用的模式。
|
|
|
|
:param cache_name: 缓存名称
|
|
:return: Redis 键匹配模式
|
|
"""
|
|
return self.domain_support.build_cache_name_pattern(cache_name)
|
|
|
|
def build_clear_target_pattern(
|
|
self,
|
|
*,
|
|
cache_name: str,
|
|
cache_key: str,
|
|
clear_all: bool,
|
|
) -> str | None:
|
|
"""
|
|
构建缓存清理目标的 Redis 键匹配模式。
|
|
|
|
:param cache_name: 缓存名称
|
|
:param cache_key: 缓存键名片段
|
|
:param clear_all: 是否清理全部缓存
|
|
:return: Redis 键匹配模式;全部清理时返回 `None`
|
|
"""
|
|
if clear_all:
|
|
return None
|
|
if cache_name:
|
|
return self.domain_support.build_cache_name_pattern(cache_name)
|
|
return f'*{cache_key}'
|