Files
XCEngine/docs/plan/Library启动Bootstrap与SourceHash校验解耦修复计划_2026-04-11.md

5.7 KiB
Raw Blame History

Library启动Bootstrap与SourceHash校验解耦修复计划

日期2026-04-11

0. 计划定位

这份计划专门处理当前 Library 主线收口时暴露出来的新根因问题:

  1. SetResourceRoot()BootstrapProjectAssets() 接到了启动同步路径。
  2. BootstrapProjectAssets() 进一步进入 AssetDatabase::Refresh()
  3. Refresh() 在扫描 Assets/cloud.nvdb 时同步计算 sourceHash
  4. cloud.nvdb 是超大源文件,导致 editor 启动直接卡在主线程。

本计划不回退单文件 artifact container不推翻 @entry=main,也不回退现有 Library 架构。

1. 当前根因

已经确认的实际阻塞链路如下:

  1. ResourceManager::SetResourceRoot()
  2. BootstrapProjectAssets()
  3. AssetImportService::BootstrapProject()
  4. AssetDatabase::Refresh()
  5. EnsureMetaForPath(Assets/cloud.nvdb)
  6. ComputeFileHash(cloud.nvdb)

结论:

  1. 慢的不是 ArtifactContaineroffset / entry 读取。
  2. 慢的不是 VolumeField artifact payload 本身。
  3. 真正把时间炸掉的是“启动阶段同步执行大源文件内容级校验”。

2. 修复目标

本计划的目标不是取消 Library 启动检查,而是把检查做对。

目标如下:

  1. 打开项目时仍然会检查 Library
  2. 启动检查只做便宜元数据检查,不做大文件内容级哈希。
  3. BootstrapEnsureArtifact / Reimport 的职责彻底拆开。
  4. sourceHash 只在真正需要导入、重导入、显式全量重建时才计算。
  5. VolumeShaderModelMaterial 在现有 container 架构下继续保持功能正确。

3. 核心原则

3.1 启动阶段只做便宜检查

启动阶段应该只检查:

  1. assets.db / artifacts.db 是否存在、是否可读。
  2. schema 是否匹配。
  3. 源文件是否存在。
  4. fileSize / writeTime / importerVersion / metaHash 是否变化。
  5. 哪些资源只是 DirtyCandidate

启动阶段不应该做:

  1. 对每个源文件重新算 sourceHash
  2. 对所有资源同步 ImportAsset
  3. 对大资源执行内容级证明。

3.2 sourceHash 只服务导入正确性

sourceHash 的职责应该下沉到真正需要它的地方:

  1. EnsureArtifact()
  2. ReimportAsset()
  3. ReimportAllAssets()
  4. 用户显式 RebuildProjectAssetCache()

3.3 日常启动和冷启动重建要分开

语义上必须区分:

  1. 日常启动:
    • 快速检查
    • 只找出可能脏的资源
    • 不同步重导所有大资源
  2. 删除 Library 后的首次冷启动:
    • 允许重建索引和数据库
    • 但依然不应该把所有超大源文件的内容校验都塞进主线程同步路径

4. 计划拆解

阶段A冻结当前正确成果

目的:

  1. 不回退 ArtifactContainer
  2. 不回退 @entry=main
  3. 不破坏 ArtifactDB schema=2
  4. 不破坏 runtimeLoadPath 现有语义

交付标准:

  1. Library 统一容器计划正式转入阶段归档。
  2. 后续启动链路修复不影响现有 container 主线。

阶段B拆开 Bootstrap 与导入职责

动作:

  1. 调整 AssetImportService::BootstrapProject() 的语义。
  2. AssetDatabase::Refresh() 只负责 fast refresh。
  3. 明确 Refresh() 不再承担内容级导入校验责任。

交付标准:

  1. SetResourceRoot() 不再把大文件 sourceHash 强行拉进启动同步路径。
  2. assets.db 仍能在启动时正确恢复。

阶段C把脏判断改成元数据优先

动作:

  1. EnsureMetaForPath() 中优先使用:
    • sourceFileSize
    • sourceWriteTime
    • metaHash
    • importerVersion
  2. 启动扫描阶段只更新这些便宜字段。
  3. 明确区分“元数据变化”和“必须立刻重导”。

交付标准:

  1. 打开项目时不会因为 cloud.nvdb 被同步全量哈希而长时间阻塞。
  2. 资源脏状态仍可被发现。

阶段D把 sourceHash 下沉到真正需要的路径

动作:

  1. EnsureArtifact() 真正需要生成或验证 artifact 时,再决定是否补做 sourceHash
  2. ReimportAllAssets()RebuildProjectAssetCache() 继续保留严格路径。
  3. 对已有 artifact 且 size/writeTime/meta/importerVersion 未变化的资源,优先直接复用。

交付标准:

  1. 日常启动快。
  2. 显式重导仍然正确。
  3. VolumeFieldImporter 不再在启动同步阶段把大文件成本炸出来。

阶段EVolume 与 Editor 回归

动作:

  1. 回归 VolumeFieldLoader.AssetDatabaseCreatesVolumeArtifactAndReusesItWithoutReimport
  2. 回归 VolumeFieldLoader.ResourceManagerLoadsVolumeByAssetRefFromProjectAssets
  3. 回归 editor 打开 project 的启动路径
  4. 回归 asset / ui / shader / gaussian_splat

交付标准:

  1. project/Library 删除后可重新生成。
  2. editor 打开项目不再出现 30s 级主线程阻塞。
  3. cloud.nvdb 在真正请求时仍能正确导入并渲染。

5. 风险控制

  1. 不能为了消掉启动卡顿,直接把 sourceHash 整体删掉。
  2. 不能回退当前 Library 单文件 container 主线。
  3. 不能把 Bootstrap 改成完全不检查 Library,否则会把错误拖到运行时爆炸。
  4. 必须特别盯住 Volume,因为它是最能放大启动语义错误的大资源类型。

6. 完成定义

当以下条件全部满足时,本计划收口:

  1. 打开项目时 SetResourceRoot() 不再同步对 cloud.nvdb 做内容级哈希。
  2. project/Library 删除后重新打开项目,数据库能够恢复。
  3. cloud.nvdb 在真正被请求时仍能正确生成 volume artifact。
  4. Volume / Asset / UI / Shader / GaussianSplat 关键回归全部通过。
  5. 启动检查、按需导入、显式全量重建三种语义边界清晰稳定。