wp-knowledge 0.13.0

KnowDB loader and SQLite-backed query facade for the Warp Parse stack.
Documentation
# wp-knowledge Provider 与 Cache 方案

中文 | [English]../../en/architecture/provider-cache.md

配套任务见:

- [Provider / Cache 重构后续任务]../tasks/provider-cache.md

## 一句话结论

目标架构很简单:

- provider 可替换
- cache 分层明确
- reload 有统一失效语义
- 旧 facade 继续可用,但内部只走统一 runtime

正确性的核心只有两个值:

- `datasource_id`
- `generation`

所有 cache 和线程本地快照都必须绑定这两个值。

## 为什么要改

旧实现主要为 `SQLite + 单进程 + 单次计算内缓存` 设计。现在同时支持 SQLite / PostgreSQL / MySQL 后,问题会直接暴露为正确性和维护成本:

- provider 生命周期过静态
- 调用方自带 cache key,语义不统一
- 元数据缓存没有边界
- `ThreadClonedMDB` 缺少版本感知

## 目标模型

内部只保留四层:

1. `DatasourceRegistry`
   - 持有当前激活 provider
   - 管理 `datasource_id`
   - 管理 `generation`
   - 处理 replace / reload
2. `KnowledgeProvider`
   - 只负责执行查询
   - 不负责缓存策略
3. `QueryRuntime`
   - 负责 cache key、cache 判定和执行路径
   - 持有 result cache 与 metadata cache
4. `Facade Compatibility Layer`
   - 保留 `query/query_row/query_named/cache_query`
   - 只做兼容,不承载核心语义

## 核心契约

### `DatasourceId`

- 表示当前数据源身份
- 可来自配置 hash 或 authority 路径 hash
- 只用于区分来源,不暴露凭据

### `Generation`

- 表示当前数据源版本
- 只要 reload、provider 切换、authority 重建、schema refresh,就必须递增
- 它是主失效机制;TTL 只是兜底

### `QueryRequest`

内部统一查询模型,至少包含:

- `sql`
- `params`
- `mode`
- `cache_policy`

provider 内部各自完成参数绑定,runtime 不再直接依赖 `rusqlite::ToSql`。

### `CachePolicy`

只保留三种语义:

- `Bypass`
  - 不走缓存
- `UseGlobal`
  - 走共享结果缓存
- `UseCallScope`
  - 走单次调用期缓存,主要为兼容旧路径

## Cache 分层

缓存只保留三层,职责不能混。

### 1. Result Cache

- 面向跨调用复用
- key 必须包含:
  - `datasource_id`
  - `generation`
  - `query_hash`
  - `params_hash`
  - `mode`
- 只适合显式允许缓存的热点查询

### 2. Local Cache

- 面向单次计算内去重
- 不承担全局一致性责任
- `FieldQueryCache` 在语义上应视为这一层

### 3. Metadata Cache

- 用于列名、schema 片段等元数据
- key 至少包含:
  - `datasource_id`
  - `generation`
  - `query_hash`
- 必须有容量上限

## Reload 契约

reload 只遵守一条规则:

- 旧 provider 是否还能用,不由时间判断,而由 `generation` 判断

因此:

- generation 变化后,result cache 自然失效
- generation 变化后,metadata cache 自然失效
- generation 变化后,`ThreadClonedMDB` 必须丢弃旧快照并重建
- reload 失败时,应保留旧 provider,不能把 runtime 切到半初始化状态

## 当前落地状态

按 2026-03-25 代码基线,核心结构已基本落地:

- `KnowledgeRuntime` 已存在,provider 可替换安装
- `QueryRequest / QueryParam / CachePolicy` 已统一
- 全局结果缓存已存在,key 已带 `datasource_id + generation`
- `FieldQueryCache` 已具备 generation 失效语义
- `ThreadClonedMDB` 已具备 generation-aware 重建能力
- SQLite metadata cache 已改为 bounded `LruCache`

主要剩余工作还有两类:

- 宿主侧 telemetry / metrics adapter
- 兼容接口的收缩与弃用策略

## 迁移顺序

建议继续按下面顺序推进:

1. 完成 reload 与 observability 对外契约
2. 收敛 provider-neutral API 为默认入口
3. 缩减 `query_named(...)` / `cache_query(...)` 的历史角色
4. 只在必要处保留 local cache 兼容层

## 最终判断

这个方向已经验证成立,后续重点不是“重新设计”,而是把剩余兼容层和宿主接入收尾做干净。