LWE 长运行验收的完成状态与通过条件
10 月 13 日,LWE 的 Scene 壁纸长运行验收已经完成了 100 次 Scene → Video → Scene 往返,有效场景呈现时间也超过了 24 小时。后端正常清除壁纸、关闭并退出,记录器最后却返回了退出码 1,systemd 将服务标为 failed。
这次没有发生需要重启的运行崩溃。完整计划还要求十次真实休眠恢复,而这一项没有完成。报告中的 status=completed 和 passed=false 都需要保留:前者记录本轮运行已经正常结束,后者记录完整验收条件尚未满足。
真实休眠会连同桌面上的验收执行环境一起挂起,当时明确延后了这部分,记录器没有主动请求休眠。最终的 0/10 表示没有完成真实休眠恢复验收,不能读成尝试了十次、失败了十次。
本轮得到的结果如下:
| 验收项 | 目标 | 本轮结果 |
|---|---|---|
| 有效场景呈现时间 | 至少 86400 秒 | 86409.47 秒,达到 |
| 完整 Scene → Video → Scene 往返 | 100 次 | 100 次,达到 |
| 真实休眠恢复 | 10 次 | 0 次,未完成 |
| 关闭并等待后端退出 | 正常完成 | 已完成,子进程退出码 0 |
| 完整验收 | 全部条件满足 | passed=false |
这里的“24 小时”按相邻的运行采样累计:场景已切换成功、后端健康、没有暂停、会话没有锁定,并且主场景的呈现计数持续增长,才有资格累计时长。主场景长运行期间还要保持同一个渲染器实例;采样间隔过长,也不能把中间那段时间直接补进去。
此外,本次把有效呈现速率的门槛定在帧率上限的 70%。上限是 30 FPS,对应每个采样区间至少 21 次完成的 swap/s。这个阈值是本轮验收规则,不是对显示器实际刷新率的测量。
最终有 117 个低于门槛的采样区间,合计 585.18 秒,没有累加到 24 小时有效时长里。它们仍保留在原始记录和整体呈现速率统计中。最终统计的整体呈现速率约为 27.76 swap/s;只看通过有效时长门槛的区间,则约为 27.81 swap/s。报告把低速区间记作 starved,这项计数本身不能说明究竟是哪一环限制了速率。
本文的约 27.76 swap/s 与帧流水线性能排查中的约 15 FPS,来自不同测试输入和采样窗口,不能拼成一条性能提升时间线;这里不对两者差异的原因作推断。
一次完整往返要求 Scene → Video 和 Video → Scene 两段都得到最终确认,同一个周期只能记一次。发出切换请求或者只切到 Video,都不足以增加完整往返数。最终复核对上了连续的 100 个周期和 200 段已确认切换。
为了让这些数字能对应到同一次运行,第三轮使用了独立的用户服务、全新的计数器和 Restart=no。源码、二进制、项目、资源和视频输入的身份在启动时固定,并在结束时重新核对。即使 Git HEAD 没变,未提交源码也可能变化,所以源码指纹需要覆盖实际参与构建的文件,不能只保存一个提交号。
服务本身也要核对 invocation、PID 的启动身份和 cgroup。最后确认它没有重启,主运行只有一个连续片段。此前已经中断的运行单独保留,不把几段运行时长加起来,写成一次不间断验收通过。否则中途重建后端带来的资源释放,也会被混进“长期运行仍然稳定”的结论。
这次给记录器增加的收尾策略,是在有效时长和切换目标达到后正常停止,即使休眠目标仍然缺失。停止原因明确写出“长运行和切换达标,休眠未完成”,同时保存已经完成和仍未完成的组件。停止请求发出后,还要等后端真正退出,核对清除、关闭和 join 的结果。
下面是本轮结果的简化状态示意,只解释各层状态的含义:
| 状态所在层 | 本轮值 | 回答的问题 |
|---|---|---|
| 运行记录 | completed | 本轮是否已经正常收尾? |
| 后端子进程 | 退出码 0 | 被测后端是否正常退出? |
| 验收判定 | passed=false | 完整条件是否全部满足? |
| 记录器进程 | 退出码 1 | 是否可以向调用方报告整体验收通过? |
systemd 不会解析验收报告里的完成组件。按照它的服务规则,Restart=no 不自动重启;Restart=on-failure 在非零退出等条件下会触发重启,另外还受成功退出状态和阻止重启状态等配置影响。具体规则见 systemd.service 官方文档。
因此,这轮服务显示 failed,与报告记录“正常完成了长运行部分”可以同时成立。自动跟进如果只看到退出码 1 就重跑,已经完成的 24 小时会被再跑一次,缺失的真实休眠证据仍然不会自动出现。这里保留退出码 1,让组合验收继续表达未通过;是否补做、补做哪一项,由报告中的停止原因和未完成组件决定。
资源数据需要放在同样明确的范围里解释。这轮按照预先设定的预算检查了预热后的 RSS、PSS、文件描述符和线程增长,相关条件通过;它还不能证明程序没有内存泄漏。
最后十二个主场景采样的平均 RSS 约为 49.70 MiB,PSS 约为 43.04 MiB,另有约 165.69 MiB 的 SwapPSS,后两项合计约 208.73 MiB。只展示 RSS 下降,会漏掉已经换出的那部分内存。
Linux 的 proc 文件系统文档 区分了这些指标:RSS 记录驻留在内存中的映射,PSS 按共享比例分摊驻留页,SwapPSS 记录按比例分摊的交换空间占用。本轮 RSS 的下降包含换出和干净文件页回收,不能全部归因于程序释放了分配。这些运行中快照也不能替代关闭后的资源检查,更不能证明所有原生分配和 GPU 资源都没有泄漏。
收尾检查确认了自有记录器和子进程已经退出,服务 cgroup 为空,自有音频采集已释放,固定源码、二进制和输入没有变化。配置文件与保存的基线一致,不过这份基线是在初始隔离切换后取得的,不能扩大成覆盖整个任务开始前状态的证明。
这份结果可以支持“本轮长运行与切换目标已经完成”。十次真实休眠恢复仍留在待验收项中,后续需要核对成对的内核休眠记录、恢复后的会话和分配状态,以及画面继续呈现的证据。锁屏、时间空档或普通暂停恢复,都不能替这一项增加次数。