跳转到内容

播放后台任务

播放后台任务使用当前进程的 active room 集合作为调度边界。这里的 active room 指本节点 ConnectionRuntime 中至少有一个 Realtime 连接的房间。

播放后台任务在每个节点运行。每个节点只扫描自己正在承载连接的房间,因为这些连接代表本进程真实持有的房间生命周期。

这个边界适用于:

  • 播放时长探测;
  • 播放自动切换;
  • 播放资源生命周期任务。

全局热门房间统计属于 presence 和分析数据,适合房间列表、管理视图和 metrics。播放后台任务读取 ConnectionRuntime::active_room_ids()

这个规则同样适用于降低后台扫描量的优化。Active room 已经因为客户端连接存在于一个或多个进程中。每个进程扫描自己的 active rooms,持久化写入路径提供锁或版本保护。

集群中同一个房间可以同时在多个节点 active。重复尝试由数据库和状态写入路径收敛:

  • 时长探测使用数据库行锁和 SKIP LOCKED 抢占任务;
  • 自动切换使用播放状态事务和乐观版本;
  • worker 的输入集合来自本节点连接,写入正确性来自持久化层。

Leader election 用于分区维护、清理和其他全局单例任务。播放生命周期 worker 的所有权来自本节点实时连接集合。

Repository 查询使用 SQLx checked macros。修改这些查询后,更新 .sqlx

Terminal window
cargo sqlx prepare --workspace -- --all-targets
SQLX_OFFLINE=true cargo check --workspace --all-targets

保留 checked macro,让 CI 的离线 SQLx 校验继续覆盖查询形状。

实现上,调度输入固定为 ConnectionRuntime::active_room_ids()。Presence hot-room 查询服务于列表、管理视图和 metrics。播放 worker 使用本节点实时连接集合,跨节点重复尝试由数据库 claim、SKIP LOCKED 和播放状态乐观版本收敛。

Room-scoped 查询需要保留 room_id = ANY(...) 过滤和当前 room_playback_progress.target_hash 连接条件。前者保持本节点 active-room 调度边界,后者把普通媒体和动态 playlist 播放都绑定到当前 target。

有限 sequential playlist 没有下一个项目时,需要持久化稳定的结束或暂停状态。继续保留旧 playing 状态会让每个扫描周期反复发现同一个已到期 source。

后台播放改动需要真实服务验证:

  • 使用构建出的 synctv 二进制启动服务,覆盖真实启动、配置、migration 和路由;
  • 用真实 WebSocket 让房间进入 active 状态;
  • synctv CLI 设置房间、媒体和播放状态;
  • curl 请求直连、代理、manifest、segment 和 Range URL;
  • 验证没有 active 连接的房间保持时长元数据不变;
  • 验证 active 房间会探测时长并在到期后自动切换一次;
  • 验证重复 worker 尝试收敛为一次状态推进。

Provider 与播放链路的手动 E2E 需要覆盖完整 PlaybackResult:Direct URL、Alist、Emby、Jellyfin、Bilibili 匿名播放、RTMP、live proxy、HLS、FLV、每个 mode、每个 direct/proxy URL、manifest、indexed segment、字幕、danmaku、thumbnail、Range、缓存命中/未命中、URL 过期和资源清理。动态 playlist 还需要覆盖路径返回、媒体解析、切换、封面/thumbnail 路由和自动切换后的 target 变化。

Provider 清单需要包含缓存命中。缓存命中和新鲜 provider 响应必须暴露相同可用的 mode 名称和 resolver action,包括 MPD/HLS manifest 与 indexed segment 路由。

RTMP 和 live proxy 验证应覆盖完整生命周期:用 CLI 创建 publish key 或 live proxy 媒体,用 ffmpeg 等真实上游推流,读取 stream info,请求 HLS playlist/segment 和 FLV,断开 viewer 或 publisher,然后确认 idle cleanup 释放流资源。

CLI 缺少工作流时先补 synctv CLI,再用 CLI 与 curl 完成验证。