文章

MiguDelay 架构 26:当前分支差异、风险与维护建议

MiguDelay(DDLive)项目架构系列文档:当前分支差异、风险与维护建议。内容基于 2026-08-04 对指定重构分支的源码扫描结果整理。

MiguDelay 架构 26:当前分支差异、风险与维护建议

系列导航系列总览 · 上一篇:MiguDelay 架构 25:构建、依赖、测试与验证边界 · 下一篇:MiguDelay 架构 27:关键类索引与阅读路径

扫描基线

  • 项目:MiguDelay(DDLive)
  • 分支:refactor/video-frame-provider
  • HEAD:d28ec061406e4e3df93e3d1a92478d71a9ad4908
  • 工作树:clean
  • 扫描日期:2026-08-04
  • 说明:内容以当前 HEAD 源码为准;仓库旧架构文档仅作为线索,不作为最终事实来源。

1. 当前分支基线

最近提交:

1
2
3
4
5
d28ec061  修复播放 UI 磁盘饼图高频刷新
774fee4d  record journal
48ea15e6  archive playback flow docs
a83d636a  同步架构瘦身后的流程文档
1be65e34  record journal

仓库现有架构 README 仍标注 1be65e34,本知识库已按 d28ec061 重新核验。

2. 已确认的当前差异

  • 最新核心架构与 a83d636a 文档基本一致。
  • d28ec061 主要是 Aux 标记栏磁盘饼图更新优化和校验测试。
  • 当前 StreamReconfiguration 没有独立 drain Port;旧工作树方案不能写入当前文档。
  • 现有 docs 中使用智能引号的 Mermaid label 可能受不同渲染器影响;本包全部改为简单标准语法。

3. 架构优势

  • 权威状态 owner 明确。
  • typed command/event/result 隔离 raw JSON 和 std::any
  • task generation + ticket + barrier 对异步结果关联较完整。
  • Output mode 和 Aux frame source 以窄 Port 注入媒体线程。
  • Preview 页面生命周期与后台任务解耦。
  • Runtime shutdown 顺序显式。
  • focused test 覆盖主要服务规则。

4. 主要风险

4.1 新旧双层复杂度

新 Service、Binding、Gateway 与旧 TaskHandle、Output 同时存在,调用链长。排障需要跨四层,命名不一致时容易误判 owner。

4.2 TaskHandle 单槽假设

push context 使用 key 0;多资源 typed ledger 最终仍落到单槽 legacy map。若未来支持多任务或多输出,需要先明确底层资源键。

4.3 Output 复杂度

Output 同时承担缓存、时钟、PTS 恢复、多音轨对齐、mode 路由、Aux、Preview、record/push callbacks 和 delay generation。它仍是高复杂度热点。拆分应围绕纯计算和数据通路,不应只为 mock 再增加代理。

4.4 Stream reconfiguration restart 竞态

requestCurrentTaskRestart()cancelAll() 后立即 restart;旧 worker 在不可中断 legacy call 内可能仍运行。generation 会过滤结果,同 target mutex 会串行局部请求,但真实资源交叉仍需压力测试。

4.5 AppConfig 大单例

配置、协议路由、检测、主备、机审、UI 信号集中,仍可能成为第二状态源。新领域状态不得反向同步为可写 AppConfig 真值。

4.6 Transfer 代码复制

媒体类复制到 transfer/module,修复不同步风险高。

4.7 测试替身膨胀

Runtime 测试有大量 factory stub。若每个构造细节都要求新 interface,可能为测试增加生产复杂度。应优先测试稳定边界与行为,不测试私有组装实现细节。

5. 建议优先级

  1. 建立真实媒体、网络、shutdown 场景测试清单并自动采集日志。
  2. 为 StreamReconfiguration 增加资源级竞态测试,先证明确有问题再设计 drain。
  3. 将 Output 中可纯化的时钟、audio sample planner、mode routing 提取为无状态算法。
  4. 明确 TaskHandle context key 模型和多输出能力。
  5. 逐步缩小 AppConfig,先迁移只读 config snapshot factory。
  6. 评估主程序与 transfer 共用媒体库,避免源码复制。
  7. 保持 Binding 语义化,不建立万能 LegacyFacade

6. 反过度设计判定

出现以下情况应警惕:

  • 一个接口只有一个方法、唯一实现、没有线程或第三方边界,且只为单元测试替换。
  • Binding 再代理另一个 Binding。
  • ViewModel、Service、Adapter 都保存同一状态副本并互相同步。
  • 为每个 callback 单独创建 owner 类,但没有独立不变量。
  • 用 mock 可见性作为生产 API 的主要设计理由。

合理抽象通常至少隔离以下之一:权威状态、线程切换、第三方 API、生命周期 gate、raw/typed 数据转换或可复用纯策略。

7. 源码证据

  • 当前 HEAD 全树
  • src/code/module/playback/**
  • src/code/module/taskhandle/**
  • src/code/module/output/**
  • tests/**

系列导航系列总览 · 上一篇:MiguDelay 架构 25:构建、依赖、测试与验证边界 · 下一篇:MiguDelay 架构 27:关键类索引与阅读路径

本文由作者按照 CC BY 4.0 进行授权