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.ts 里 views:{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 行真正生效;更进一步可让 listViews 与 listViewOverrides 共享同一份 type='view' 枚举结果(两者本来就读同一批行,data-objectstack 的 listViewOverrides 读的是 meta/{对象名}(把对象名当 metadata type),写却落在 type='view' —— 两边键空间不相交,已保存的视图个性化永远读不回来 #3774 后连「属于哪个对象」的判断都已收敛到同一个 viewItemObjectName() accessor 了),一次页面加载省掉一次往返。

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

相关


Generated by Claude Code

Activity

  1. os-zhuang commented on Aug 10, 2026

    @os-zhuang
    Contributor

    Finding-triage ruling: Hold (why still held): the four invalidate calls target a views: cache key no read path ever writes (index.ts:2776/2937/2970/2987) — listViews is effectively uncached and the lines are inert; enforce-or-remove (add caching vs delete the no-ops) is a pick nobody needs today. Restart: next card touching data-objectstack caching, or the next dead-code sweep.

    Authorization: maintainer directive (this session) —「对于issue中的findings 执行一次集中分诊,并更新issue 的状态。」Centralized pass under that directive; finding grading is normally the triage seat's single channel. Round: objectstack#4949 finding-triage, 2026-08-10.
    Session: 01JaVVMrSxt7Tgi1uwEuDtH7


    Generated by Claude Code

  2. claude commented on Aug 10, 2026

    @claude
    Contributor

    Findings triage (re-verify @ origin/main da81093): HOLD — data-objectstack/src/index.ts still has 4 invalidate calls on views:{objectName} and still zero writers of that key (counter-checked: no metadataCache.get(\views:`)anywhere in the file), solistViews()remains uncached and the 4 lines remain no-ops. The remove-vs-enforce fork changes cache semantics (draft-preview keying), so it stays a recorded observation until someone rules a direction.finding` stands.

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  3. claude commented on Aug 11, 2026

    @claude
    Contributor

    Findings cadence (triage seat): HOLD — re-verified on origin/main @ e1ade8f: still exactly 4 invalidate calls for views:${objectName} in packages/data-objectstack/src/index.ts and 0 writers among the 8 metadataCache.get sites — listViews remains uncached and the 4 lines remain inert. Dormant-code class (symptom is a missing cache layer, not wrong data); exit is add-the-cache vs delete-the-lines, unpicked.

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  4. os-zhuang commented on Aug 11, 2026

    @os-zhuang
    Contributor

    Findings triage (cadence re-verify @ origin/main 5e2e9fa): HOLD as finding, with measured drift — the dead-invalidate count has grown from the filed 4 to 5 sites (packages/data-objectstack/src/index.ts:2888/:3049/:3109/:3140/:3157, all views:${objectName}), while the write side still does not exist: every metadataCache.get cacheKey in the file is view-overrides:, view:{obj}:{id}, app:, page: or {category}:{name} (:2797/:2834/:2884/:3176/:3197/:3605) — nothing ever populates a views: key, so listViews remains uncached and the five lines stay inert. The class keeps growing as new save paths copy the pattern, which slightly strengthens the case for promoting into a small clean-up card (delete the key or actually cache listViews under it) — held one more rotation; promote on the next drift observation or any listViews caching work.

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  5. os-zhuang commented on Aug 11, 2026

    @os-zhuang
    Contributor

    Findings triage (cadence re-check): HOLD as finding — premise stable at last round's drifted count.

    • Re-verified on origin/main @ b954120: dead invalidate?.(\views:…`)calls remain at **5** (the 4→5 drift noted last round has not moved again), and there is still **zero**metadataCache.get(`views:…`)— the key is invalidated but never written/read;listViews` remains uncached.
    • Direction (remove the dead invalidates vs give listViews a real cache sharing the type='view' enumeration) still needs the seat's pick at promotion time; efficiency-only impact, nothing a user hits.
    • Rotation note: two consecutive stable checks post-drift; back-of-rotation candidate next cycle if frozen again.

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  6. os-zhuang commented on Aug 11, 2026

    @os-zhuang
    Contributor

    Findings triage: promoted — finding → pm:queue as a member of sweep #4328 (dead-surface deletions batch 3). Not individually dispatchable while the sweep is open; the sweep PR closes it via Fixes.

    Premise re-verified on origin/main @ b16be40, with one drift note: there are now five (not four) metadataCache.invalidate?.(views:${objectName}) sites in packages/data-objectstack/src/index.ts (:3022, :3183, :3243, :3274, :3291), and still no write path — no views:-keyed metadataCache.get/set anywhere, so listViews remains genuinely uncached and all five invalidations are dead code.

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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