Files
ft/CodexOutput/upserver/B3BatchMigration/M2/M2-KVMgr层级依赖纠偏意见-待审.md
Liubing\LB 6813da149a feat(upserver): 保存M2客户端KV迁移至本人统计写检查点
保存独立KV用户服务、固定会话存档与原业务接线,以及C3d资料缓存和C3e本人统计写。
保留原PF/AGG路线、业务公式和时序;榜单读取、好友资料、公告、匹配及首场景闸仍待完成。

验证:ServiceHost两条件各33组646断言;Unity CLI Loop编译0错误269警告。
包含相关方案、评审裁决、测试及状态文档。未操作服务器、正式账号或打包。
2026-09-30 19:19:05 +08:00

42 lines
5.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# M2:KVMgr层级依赖纠偏意见(主会话,待完整方案审查)
日期:2026-09-29。用户指出:PlayFabMgr原本作为存档底层入口,KVMgr也应提供底层函数,上层业务和Service依赖它,不能由KVMgr反向调用外部Service。此意见成立;本文纠正[M2底稿](M2-旧方法与调用方合并设计底稿.md)的层级表述,不修改B02受审交付或生产代码。
## 源码事实与责任
当前`Client/Assets/Scripts/Core/KVMgr.cs`只有四个显式handle入口,没有直接Resolve或调用`UserService`、`CustomServerMgr`、UI或业务模型;它调用`PlayerKVGameSessionHandle`的读、写、Flush、Wait。这一部分是薄存档门面。问题是`KVMgr`位于`Core`,却引用位于`Services/PlayerData`的`PlayerKVGameLoadGuard`、`PlayerKVGameSessionHandle`、`KVSnapshot`和结果类型;尤其`PlayerKVGameLoadGuard`由`PlayerKVGameLoadCoordinator`进入/释放,属于加载阶段的编排门。`KVMgr`直接检查它,形成了底层存档入口对上层加载规则的反向依赖。当前均在同一HotUpdate编译域,编译通过不证明层级合理。
B02修订2的目标和审查仅是四入口**逐字行为等价搬迁**,所以原PlayFabMgr块中的guard检查被原样搬入KVMgr。复核PASS证明等价和兼容,不证明层级设计正确。主会话此前把“等价”误当成“可沿此结构扩展”,这一推论撤回。B02的44项hash和限定关闭事实保持,不倒改受审源码;纠偏属于下一完整设计和独立审查范围。
## 应有依赖方向
```text
玩法/UI/数据模型 → 业务操作或所属Service → KVMgr存档入口 → 固定会话Handle/Owner/KV存储
↑
登录/加载/退出编排 ── 发布或撤销原Handle、控制存档可用阶段
```
- `KVMgr`只负责显式handle的键读、键写、Flush和原票据等待,以及这些操作自身的输入、句柄状态和结果;不获取当前账号,不调用Service、业务事件或UI,不管理登录、31模块Apply或生命周期。
- 登录/加载Service拥有认证、解码、31模块Apply、原handle发布和关闭屏障。业务操作在首次模型变化前捕获由所属Service显式传入的原handle,之后只向KVMgr传它;旧回调不能重新查“当前”Service或Owner。
- 加载期间禁止外部读写的门必须落在**存储模块可供上层控制的准入契约**:加载编排调用其Enter/Exit,KVMgr只检查同模块的准入状态;不得让KVMgr反向依赖`PlayerKVGameLoadCoordinator`或业务Service。旧PlayFabMgr上的Legacy禁写诊断仍须保持,不能因移动guard而失效。
- 文件/命名空间应表达同一逻辑模块。建议把KVMgr及其直接使用的准入契约归入`PlayerDataStorage`存储模块(现有句柄/Owner所在模块),上层`UserService`、`PlayerKVGameLoadCoordinator`只从外部调用它。无需为改目录一次搬动整个KV引擎;具体文件白名单和Unity meta/GUID处理须在完整方案中列清。
## 路线比较与建议
| 方案 | 影响 | 裁量 |
|---|---|---|
| 推荐:存储模块内的薄KVMgr+下沉准入契约,上层显式发布原handle | 定向修正guard依赖;保留现有Handle/Owner/缓存/同步引擎及四入口结果合同,需验证加载禁写与旧PF诊断 | 作为M2正式方案的优先路线 |
| Core单独定义接口/DTO,Services实现并注入KVMgr | 编译层级最显式,但现有结果、Handle、Owner类型要抽取/适配,改动面大 | 当前最小迁移不采用 |
| 保持Core→Services/PlayerData和现有guard检查,直接扩展旧PF兼容函数 | 眼前改动少,但继续强化反向依赖,正式接线更难审 | 不作为后续设计基线 |
此处的“下沉准入契约”**不是**新增全局当前账号或第二套缓存。它只表达当前加载阶段是否允许外部KV调用;原handle仍由上层操作显式持有。是否移动现有`PlayerKVGameLoadGuard`本体或抽出共享的最小状态,必须以当前21处guard引用和加载竞争测试为边界做一次完整设计,不能在编码时临时选。
## 下一份完整方案必须补齐
1. 精确分层图、KVMgr/准入契约/会话Service的源码白名单和调用方向;显式说明Core与`Services/PlayerData`现状如何纠正,以及Unity meta/GUID如何保留。
2. 准入门的时序:Prepare、31模块Apply/通知、发布、拒绝、Revoke、Close;原handle在加载中的内部读取与外部KVMgr读取必须区分,旧PF side-effect计数仍可检测。
3. 实际业务方如何得到原handle,哪一处捕获、何时撤销;读三态、写Accepted/uncertain、原票据Wait与旧epoch停止规则不变。
4. 既有B02 Route/B01/故障测试、B2加载guard、Unity双构建及必要业务回归;不因目录/准入调整重写存档格式或玩法计算。
在以上方案完整评审、主会话裁决前,不调整`KVMgr.cs`、guard、句柄、Service或业务调用。固定地址`http://s101.local:18080/`;仅用Unity CLI Loop,不使用UnitySkills,暂不打包。