# Routing Cache ## Purpose TBD - 为 Provider 和 Model 提供内存缓存,优化路由查询性能。 ## Requirements ### Requirement: RoutingCache 缓存 Provider 和 Model 系统 SHALL 为 Provider 和 Model 提供内存缓存,使用 sync.Map 作为缓存数据结构。 #### Scenario: 缓存数据结构 - **WHEN** 创建 RoutingCache - **THEN** SHALL 使用 sync.Map 存储 Provider(key = providerID) - **THEN** SHALL 使用 sync.Map 存储 Model(key = providerID/modelName) ### Requirement: 缓存查询优先 RoutingCache SHALL 优先从缓存查询,缓存未命中时查询数据库并更新缓存。 #### Scenario: 缓存命中 - **WHEN** 查询 Provider 或 Model - **THEN** SHALL 先从缓存查询 - **THEN** 如果缓存命中,SHALL 直接返回缓存值 - **THEN** SHALL 不查询数据库 #### Scenario: 缓存未命中 - **WHEN** 查询 Provider 或 Model - **THEN** SHALL 先从缓存查询 - **THEN** 如果缓存未命中,SHALL 查询数据库 - **THEN** SHALL 将查询结果存入缓存 - **THEN** SHALL 返回查询结果 #### Scenario: 双重检查防止竞态 - **WHEN** 并发查询同一个 Provider 或 Model - **THEN** SHALL 在查询数据库后再次检查缓存 - **THEN** 如果已有其他 goroutine 存入缓存,SHALL 使用缓存值 - **THEN** SHALL 防止存入旧值 ### Requirement: 缓存更新 RoutingCache SHALL 支持 Create 操作后更新缓存。 #### Scenario: Create Provider 后更新缓存 - **WHEN** 创建 Provider 成功 - **THEN** SHALL 调用 RoutingCache.SetProvider - **THEN** SHALL 将新 Provider 存入缓存 #### Scenario: Create Model 后更新缓存 - **WHEN** 创建 Model 成功 - **THEN** SHALL 调用 RoutingCache.SetModel - **THEN** SHALL 将新 Model 存入缓存 ### Requirement: 缓存失效 RoutingCache SHALL 支持 Update/Delete 操作后清除缓存。 #### Scenario: Update Provider 后清除缓存 - **WHEN** 更新 Provider 成功 - **THEN** SHALL 调用 RoutingCache.InvalidateProvider - **THEN** SHALL 清除该 Provider 的缓存 - **THEN** SHALL 级联清除该 Provider 的所有 Model 缓存 #### Scenario: Delete Provider 后清除缓存 - **WHEN** 删除 Provider 成功 - **THEN** SHALL 调用 RoutingCache.InvalidateProvider - **THEN** SHALL 清除该 Provider 的缓存 - **THEN** SHALL 级联清除该 Provider 的所有 Model 缓存 #### Scenario: Update Model 后清除缓存 - **WHEN** 更新 Model 成功 - **THEN** SHALL 调用 RoutingCache.InvalidateModel - **THEN** SHALL 清除旧位置的 Model 缓存 - **THEN** 如果 provider_id 或 model_name 变化,SHALL 也清除新位置的缓存 #### Scenario: Delete Model 后清除缓存 - **WHEN** 删除 Model 成功 - **THEN** SHALL 调用 RoutingCache.InvalidateModel - **THEN** SHALL 清除该 Model 的缓存 ### Requirement: 缓存预热 RoutingCache SHALL 支持启动时预热缓存。 #### Scenario: 预热成功 - **WHEN** 服务启动时 - **THEN** SHALL 调用 RoutingCache.Preload - **THEN** SHALL 从数据库加载所有 Provider 到缓存 - **THEN** SHALL 从数据库加载所有 Model 到缓存 - **THEN** SHALL 记录预热完成的日志 #### Scenario: 预热失败 - **WHEN** 预热失败时 - **THEN** SHALL 记录警告日志 - **THEN** SHALL 继续启动服务 - **THEN** SHALL 使用懒加载(首次查询时加载) ### Requirement: RoutingService 使用缓存 RoutingService SHALL 使用 RoutingCache 进行路由查询。 #### Scenario: RouteByModelName 使用缓存 - **WHEN** 调用 RoutingService.RouteByModelName - **THEN** SHALL 调用 RoutingCache.GetModel 获取 Model - **THEN** SHALL 调用 RoutingCache.GetProvider 获取 Provider - **THEN** SHALL 不直接调用 Repository ### Requirement: 并发安全 RoutingCache SHALL 支持并发访问。 #### Scenario: 并发查询 - **WHEN** 多个 goroutine 并发查询缓存 - **THEN** SHALL 无竞态条件 - **THEN** SHALL 无 panic #### Scenario: 并发查询和失效 - **WHEN** 并发查询和失效缓存 - **THEN** SHALL 无竞态条件 - **THEN** SHALL 保证一致性