该条目来自 kotlin-footguns 技能集合,讨论分布式“就绪屏障”模式在客户端实现中的陷阱。
用途与模型
多个客户端各自解码同一内容,速度不一。当某个客户端跟不上时,服务端公布仍在等待哪些成员,被点名的客户端在内容就绪后回应,直到最后一个回应到达,所有人才继续。整个模型依赖一个特性:这是对每个其他参与者的活性依赖。
主要陷阱
- 以“正在播放”作为就绪信号会造成死锁:播放恰恰是屏障在阻止的事情,应改为在加载/缓冲达到低阈值时回应。
- 未实现应答的客户端会静默冻结整组:无错误、无客户端超时、正确成员也看不到日志。应答逻辑应放在无条件启动的独立收集器中。
- 仅在名单中点名时才应答,避免噪声并让收集器在重复广播中安全运行。
- 按公告中的内容 ID 应答,而非从本地状态重新推导“当前内容”。
- 界面应显示仍在等待的成员名称,否则用户会误以为卡死并强制退出。
- 屏障完成时需清除待答名单和派生的每成员标志,最好在读取时从名单派生标志。
- 应答应为幂等而非一次性,避免首次应答在传输中丢失后再次冻结。
- 屏障不能替代位置同步,具体分工取决于服务端实现,应阅读服务端处理逻辑而非假设。
验证方法
条目给出三条 grep 检查:统计所有涉及 waitingFor/bufferReady/isBuffering 的文件(应包含协议、状态机、领域模型、应答收集器和至少一个展示文件);查找 bufferedPercentage 的读取者(应答收集器应读取缓冲而非播放标志);查找 waitingFor 的 id→名称解析位置。还建议用两个客户端、其中一个置于慢速或阻塞网络,在内容切换时验证快速客户端能按名称显示慢速客户端并在其应答后开始;再杀掉慢速客户端观察快速客户端是否会无限等待。
适用场景与限制
该条目适用于实现共享会话同步(如共同观看/共同播放场景)的 Kotlin 客户端开发者,尤其是涉及服务端就绪屏障协议的项目。资料未提供具体产品、安装步骤、价格或平台支持信息;示例代码为改编版本,消息常量是占位符。