Skip to content

data-objectstack: views:{objectName} 缓存键被 4 处 invalidate,却从没有任何读路径写入过 —— listViews 实为无缓存,那 4 行是惰性代码 #3778

Description

@yinlianghui

在做 #3774(视图 override 读写命名空间)时,顺路核对了 ObjectStackAdapter 的元数据缓存键,发现的相邻观察。不在该单范围内,按 PD #10 单独立此单,未在 PR #3777 里动。

这是 observation-class:今天没有用户会撞到它(症状只是「少了一层缓存」,不是错数据),故只打 finding,不进 pm:queue,交由分诊定级。

事实

packages/data-objectstack/src/index.tsviews:{objectName} 这个缓存键被 invalidate 了 4 次:

2775:    this.metadataCache.invalidate?.(`views:${objectName}`);   // updateViewConfig
2936:    this.metadataCache.invalidate?.(`views:${objectName}`);
2969:    this.metadataCache.invalidate?.(`views:${objectName}`);
2986:    this.metadataCache.invalidate?.(`views:${objectName}`);

没有任何路径写入过它。全文件仅 6 处 metadataCache.get(...),其 cacheKey 分别是:

cacheKey
2444 objectName(getObjectSchema)
2685 view-overrides:{objectName}
2722 view:{objectName}:{viewId}
3006 app:{appId}
3027 page:{pageId}
3389 {category}:{name}

没有 views: 前缀的那个。listViews() 自己是直接 fetch、完全不过缓存的(await this.client.meta.getItems('view'),外面没有 metadataCache.get 包裹)。

(行号取自 PR #3777 合入后的树;在 origin/main 上是同样的结构,只是行号偏移。)

推论

  • 那 4 行 invalidate惰性代码:失效一个永不存在的条目,恒为 no-op。
  • 真正的效果是 listViews() 每次调用都打一次 GET /api/v1/meta/view。ObjectView 一次页面加载里,视图切换器(listViews)与 override 批量读(listViewOverrides,有缓存)会各打一次同一个 /meta/view 路由 —— 同一份数据取两遍。

为什么现在只当观察记录

请求数没有回归:#3774 之前 listViewOverrides 打的是 /meta/{对象名},也是一次请求,只不过取回来是空的。修复只改了第二次请求的 URL,没有新增往返。所以这是一条既有的效率观察,不是 #3774 引入的。

两条可能方向(留给分诊,未擅自选)

  1. 删掉那 4 行 invalidate(enforce-or-remove 的「remove」侧):承认 listViews 就是不缓存,别留一个看起来在维护、实则空转的失效调用。
  2. listViews 补上缓存(enforce 侧),让那 4 行真正生效;更进一步可让 listViewslistViewOverrides 共享同一份 type='view' 枚举结果(两者本来就读同一批行,data-objectstack 的 listViewOverrides 读的是 meta/{对象名}(把对象名当 metadata type),写却落在 type='view' —— 两边键空间不相交,已保存的视图个性化永远读不回来 #3774 后连「属于哪个对象」的判断都已收敛到同一个 viewItemObjectName() accessor 了),一次页面加载省掉一次往返。

方向 2 更符合两个方法本已同源的现状,但它改的是缓存语义(草稿预览 previewDrafts 分支不能与已发布列表共用键),需要分诊确认后再动 —— 所以这里只记录,不实现。

相关


Generated by Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions