Repository navigation
data-objectstack: views:{objectName} 缓存键被 4 处 invalidate,却从没有任何读路径写入过 —— listViews 实为无缓存,那 4 行是惰性代码 #3778
Description
Activity
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
Findings triage (re-verify @
origin/mainda81093): HOLD —data-objectstack/src/index.tsstill has 4invalidatecalls onviews:{objectName}and still zero writers of that key (counter-checked: nometadataCache.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
Findings cadence (triage seat): HOLD — re-verified on
origin/main@e1ade8f: still exactly 4invalidatecalls forviews:${objectName}inpackages/data-objectstack/src/index.tsand 0 writers among the 8metadataCache.getsites —listViewsremains 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
Findings triage (cadence re-verify @
origin/main5e2e9fa): HOLD asfinding, 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, allviews:${objectName}), while the write side still does not exist: everymetadataCache.getcacheKey in the file isview-overrides:,view:{obj}:{id},app:,page:or{category}:{name}(:2797/:2834/:2884/:3176/:3197/:3605) — nothing ever populates aviews:key, solistViewsremains 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 cachelistViewsunder it) — held one more rotation; promote on the next drift observation or anylistViewscaching work.本评论来自分诊座位 Routine(#5474 试点),不构成认领。
Generated by Claude Code
Findings triage (cadence re-check): HOLD as
finding— premise stable at last round's drifted count.- Re-verified on
origin/main@b954120: deadinvalidate?.(\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
listViewsa real cache sharing thetype='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
- Re-verified on
Findings triage: promoted —
finding→pm:queueas a member of sweep #4328 (dead-surface deletions batch 3). Not individually dispatchable while the sweep is open; the sweep PR closes it viaFixes.Premise re-verified on
origin/main@b16be40, with one drift note: there are now five (not four)metadataCache.invalidate?.(views:${objectName})sites inpackages/data-objectstack/src/index.ts(:3022,:3183,:3243,:3274,:3291), and still no write path — noviews:-keyedmetadataCache.get/set anywhere, solistViewsremains genuinely uncached and all five invalidations are dead code.本评论来自分诊座位 Routine(#5474 试点),不构成认领。
Generated by Claude Code
- added a commit that references this issue
on Aug 17, 2026
在做 #3774(视图 override 读写命名空间)时,顺路核对了
ObjectStackAdapter的元数据缓存键,发现的相邻观察。不在该单范围内,按 PD #10 单独立此单,未在 PR #3777 里动。这是 observation-class:今天没有用户会撞到它(症状只是「少了一层缓存」,不是错数据),故只打
finding,不进pm:queue,交由分诊定级。事实
packages/data-objectstack/src/index.ts里views:{objectName}这个缓存键被 invalidate 了 4 次:但没有任何路径写入过它。全文件仅 6 处
metadataCache.get(...),其 cacheKey 分别是:objectName(getObjectSchema)view-overrides:{objectName}view:{objectName}:{viewId}app:{appId}page:{pageId}{category}:{name}没有
views:前缀的那个。listViews()自己是直接 fetch、完全不过缓存的(await this.client.meta.getItems('view'),外面没有metadataCache.get包裹)。(行号取自 PR #3777 合入后的树;在
origin/main上是同样的结构,只是行号偏移。)推论
invalidate是惰性代码:失效一个永不存在的条目,恒为 no-op。listViews()每次调用都打一次GET /api/v1/meta/view。ObjectView 一次页面加载里,视图切换器(listViews)与 override 批量读(listViewOverrides,有缓存)会各打一次同一个/meta/view路由 —— 同一份数据取两遍。为什么现在只当观察记录
请求数没有回归:#3774 之前
listViewOverrides打的是/meta/{对象名},也是一次请求,只不过取回来是空的。修复只改了第二次请求的 URL,没有新增往返。所以这是一条既有的效率观察,不是 #3774 引入的。两条可能方向(留给分诊,未擅自选)
listViews就是不缓存,别留一个看起来在维护、实则空转的失效调用。listViews补上缓存(enforce 侧),让那 4 行真正生效;更进一步可让listViews与listViewOverrides共享同一份type='view'枚举结果(两者本来就读同一批行,data-objectstack 的 listViewOverrides 读的是meta/{对象名}(把对象名当 metadata type),写却落在type='view'—— 两边键空间不相交,已保存的视图个性化永远读不回来 #3774 后连「属于哪个对象」的判断都已收敛到同一个viewItemObjectName()accessor 了),一次页面加载省掉一次往返。方向 2 更符合两个方法本已同源的现状,但它改的是缓存语义(草稿预览
previewDrafts分支不能与已发布列表共用键),需要分诊确认后再动 —— 所以这里只记录,不实现。相关
meta/{对象名}(把对象名当 metadata type),写却落在type='view'—— 两边键空间不相交,已保存的视图个性化永远读不回来 #3774 / PR fix(data-objectstack): read view overrides from the type='view' namespace they are written to (#3774) #3777(override 读写命名空间;本观察是在其测量过程中发现的)Generated by Claude Code