1) 客服 Agent 四份交付文档 + 构建脚手架:品牌由包装占位 XX科技 / 旧名 南方财富 统一为南方基金(热线 400-889-8899 / 官网 nffund.com),系统名改为「智能服务系统」; 同步追加 §0.4 修订记录行,工程记录行保留原占位字面以支撑硬编码扫描验收。 2) 开发文档:清理 28 份已作废/残留文档(14 份移出归档 + 14 份仓库副本), 新增《文档规整方案与开发前待决事项-2026-09-17》。 3) 客服agent 四份交付文档首次纳入本分支。
53 lines
1.7 KiB
Python
53 lines
1.7 KiB
Python
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)
|
|
|