mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 09:20:22 +08:00
fix(provider-mapping): 修复详情页映射延迟刷新并补齐 mapping-preview 缓存治理
- 前端:Provider 详情页在 key/模型关联/模型保存/映射保存后并行刷新 endpoints 与 mapping-preview - 前端:为 mapping-preview 请求增加 requestId 保护,避免旧响应回写覆盖新状态 - 后端:Key.allowed_models 变更时按 provider 精准失效 mapping-preview 缓存 - 后端:GlobalModel 变更(含创建)时全量失效 mapping-preview 缓存 - 监控:在 Redis 缓存分类中新增 provider_mapping_preview(admin:providers:mapping-preview:*) 验证: - frontend `npm run type-check` - backend `python -m compileall`(相关文件) - pytest 定向用例通过
This commit is contained in:
@@ -427,6 +427,12 @@ class AdminCreateGlobalModelAdapter(AdminApiAdapter):
|
||||
|
||||
logger.info(f"GlobalModel 已创建: id={global_model.id} name={global_model.name}")
|
||||
|
||||
# 创建成功后失效缓存(避免 mapping-preview 在 TTL 内读到旧结果)
|
||||
from src.services.cache.invalidation import get_cache_invalidation_service
|
||||
|
||||
cache_service = get_cache_invalidation_service()
|
||||
await cache_service.on_global_model_changed(global_model.name, str(global_model.id))
|
||||
|
||||
return GlobalModelResponse.model_validate(global_model)
|
||||
|
||||
|
||||
|
||||
@@ -1558,6 +1558,12 @@ _CACHE_CATEGORIES: list[tuple[str, str, str, str]] = [
|
||||
"model:provider_global:*",
|
||||
"Provider-GlobalModel 模型映射缓存",
|
||||
),
|
||||
(
|
||||
"provider_mapping_preview",
|
||||
"映射预览",
|
||||
"admin:providers:mapping-preview:*",
|
||||
"Provider 详情页 mapping-preview 缓存",
|
||||
),
|
||||
("global_model", "全局模型", "global_model:*", "GlobalModel 缓存(ID/名称/解析)"),
|
||||
("models_list", "模型列表", "models:list:*", "/v1/models 端点模型列表缓存"),
|
||||
("user", "用户", "user:*", "用户信息缓存(ID/Email)"),
|
||||
|
||||
42
src/services/cache/invalidation.py
vendored
42
src/services/cache/invalidation.py
vendored
@@ -6,10 +6,15 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
from typing import Any
|
||||
|
||||
from src.core.logger import logger
|
||||
|
||||
_PROVIDER_MAPPING_PREVIEW_CACHE_KEY_PREFIX = "admin:providers:mapping-preview:global"
|
||||
_PROVIDER_MAPPING_PREVIEW_CACHE_PATTERN = f"{_PROVIDER_MAPPING_PREVIEW_CACHE_KEY_PREFIX}:v:*"
|
||||
|
||||
|
||||
class CacheInvalidationService:
|
||||
"""缓存失效服务"""
|
||||
@@ -61,6 +66,12 @@ class CacheInvalidationService:
|
||||
except Exception as e:
|
||||
logger.error(f"[CacheInvalidation] 失效 models list 缓存失败: {e}")
|
||||
|
||||
# 5. 清除 Provider 映射预览缓存(GlobalModel 映射规则变化会影响所有 Provider)
|
||||
try:
|
||||
await self._invalidate_all_provider_mapping_preview_cache()
|
||||
except Exception as e:
|
||||
logger.error(f"[CacheInvalidation] 失效 Provider 映射预览缓存失败: {e}")
|
||||
|
||||
def on_model_changed(self, provider_id: str, global_model_id: str) -> Any:
|
||||
"""Model 变更时的缓存失效"""
|
||||
self._refresh_provider_cache(provider_id)
|
||||
@@ -78,6 +89,12 @@ class CacheInvalidationService:
|
||||
logger.info(f"[CacheInvalidation] Key allowed_models 变更: provider_id={provider_id}")
|
||||
self._refresh_provider_cache(provider_id)
|
||||
|
||||
# 清除该 Provider 的映射预览缓存(详情页模型映射依赖)
|
||||
try:
|
||||
await self._invalidate_provider_mapping_preview_cache(provider_id)
|
||||
except Exception as e:
|
||||
logger.error(f"[CacheInvalidation] 失效 Provider 映射预览缓存失败: {e}")
|
||||
|
||||
# 清除 /v1/models 列表缓存(allowed_models 变更会影响模型可用性)
|
||||
from src.services.cache.model_list_cache import invalidate_models_list_cache
|
||||
|
||||
@@ -92,6 +109,31 @@ class CacheInvalidationService:
|
||||
|
||||
ModelMapperMiddleware.refresh_cache(provider_id)
|
||||
|
||||
@staticmethod
|
||||
def _build_provider_mapping_preview_cache_key(provider_id: str) -> str:
|
||||
"""构建指定 Provider 的 mapping-preview 缓存键。"""
|
||||
raw = json.dumps(
|
||||
{"provider_id": provider_id},
|
||||
sort_keys=True,
|
||||
ensure_ascii=False,
|
||||
default=str,
|
||||
)
|
||||
vary_hash = hashlib.sha1(raw.encode("utf-8")).hexdigest()[:16]
|
||||
return f"{_PROVIDER_MAPPING_PREVIEW_CACHE_KEY_PREFIX}:v:{vary_hash}"
|
||||
|
||||
async def _invalidate_provider_mapping_preview_cache(self, provider_id: str) -> None:
|
||||
"""失效指定 Provider 的 mapping-preview 缓存。"""
|
||||
from src.core.cache_service import CacheService
|
||||
|
||||
cache_key = self._build_provider_mapping_preview_cache_key(provider_id)
|
||||
await CacheService.delete(cache_key)
|
||||
|
||||
async def _invalidate_all_provider_mapping_preview_cache(self) -> None:
|
||||
"""失效所有 Provider 的 mapping-preview 缓存。"""
|
||||
from src.core.cache_service import CacheService
|
||||
|
||||
await CacheService.delete_pattern(_PROVIDER_MAPPING_PREVIEW_CACHE_PATTERN)
|
||||
|
||||
def clear_all_caches(self) -> None:
|
||||
"""清空所有缓存"""
|
||||
from src.services.model.mapper import ModelMapperMiddleware
|
||||
|
||||
Reference in New Issue
Block a user