from typing import Any, Protocol class CacheClient(Protocol): async def get(self, key: str) -> Any: ... async def set(self, key: str, value: str, ex: int | None = None) -> Any: ... class CacheReadResult: def __init__(self, value: Any, degraded: bool = False) -> None: self.value = value self.degraded = degraded class MemoryCacheAdapter: """Cache is an optimization; failures must not block MySQL recall.""" def __init__(self, client: CacheClient) -> None: self.client = client async def get(self, key: str) -> CacheReadResult: try: return CacheReadResult(await self.client.get(key)) except Exception: return CacheReadResult(None, degraded=True) async def set(self, key: str, value: str, ttl_seconds: int = 300) -> bool: try: await self.client.set(key, value, ex=ttl_seconds) return True except Exception: return False async def delete(self, *keys: str) -> int: """删除若干缓存键;客户端不支持删除时返回 0,缓存只是可重建的优化层。 记忆热缓存按客户维度失效,失效失败不得阻塞主流程,因此这里吞掉异常, 由调用方通过返回值与 `degraded` 语义决定是否告警。 """ targets = [key for key in keys if key] if not targets: return 0 delete = getattr(self.client, "delete", None) if delete is None: return 0 try: removed = await delete(*targets) except Exception: return 0 return int(removed) if isinstance(removed, int) else len(targets)