fix: 0-segment retry loop, event bus isolation, and dashboard snapshot serve - #117
fix: 0-segment retry loop, event bus isolation, and dashboard snapshot serve#117sheepweb wants to merge 9 commits into
Conversation
RecordingStopped now carries segmentsDispatched count from pollingLoop. SchedulerComponent only re-arms when >0 segments were actually dispatched. Rooms that return 404 before any download (index=-1 / 0 segments) wait for RoomStatusChanged instead of entering an infinite start-stop cycle. Also fixes silent session discard: startSession no longer silently returns when stuck in Fetching state — it cancels the stale pollingJob and allows re-entry. configureSession failure now publishes RecordingStopped(0) to properly notify the scheduler.
0-segment RecordingStopped now retries with backoff (30s/60s/120s/240s/480s) instead of permanently giving up. Max 5 attempts, then waits for RoomStatusChanged. This prevents rooms that are genuinely public but experience transient CDN unavailability from being stuck forever, while still avoiding the infinite zombie loop.
…0-segment failures
…tivated Removed max retry limit and exponential backoff. 0-segment RecordingStopped now retries every 30s indefinitely. The loop terminates naturally when the room is deactivated or the system shuts down - no artificial cap needed.
Track rooms currently in a recordable state (public, or groupShow with autopay). 0-segment retries now continue every 30s while the room remains recordable and stop automatically once RoomStatusChanged reports an unrecordable state or the room is deactivated.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
| val client = ClientManager.getProxiedClient("api") | ||
| val response = withRetry(3) { | ||
| client.get("https://stripchat.com/api/front/v3/config/initial") { | ||
| client.get("https://poplive.xyz/api/front/v3/config/initial") { |
| try { | ||
| val client = ClientManager.getProxiedClient("event") | ||
| client.webSocket("wss://websocket-v6.xhamsterlive.com/connection/websocket") { | ||
| client.webSocket("wss://websocket-v6.poplive.xyz/connection/websocket") { |
There was a problem hiding this comment.
连不上,再确认一下poplive和xhamsterlive到底是不是一样,尤其是直播间内消息和流地址
| } | ||
|
|
||
| fun snapshotRooms(): List<Room> = rooms.values.map { it.copy() } | ||
|
|
There was a problem hiding this comment.
这种不要单独开一个函数然后注入HttpComponent,eventBus的存在就是尽可能降低组件之间来回注入的。
如果觉得会导致Bus卡住应该在命令收发侧去调试, 或者设计全异步的命令处理流程
| ) : Actor<SchedulerMsg>("SchedulerComponent", eventBus, parentScope) { | ||
|
|
||
| private val armed = ConcurrentHashMap<Long, ArmedRoom>() | ||
| private val recordableRooms = ConcurrentHashMap.newKeySet<Long>() |
There was a problem hiding this comment.
看了一圈这个变量除了记录当前状态还有别的做用吗。
Scheduler不需要缓存当前房间是否可以录制,只需要在每次尝试启动Session之前判断是否可以录制即可
| val client = ClientManager.getProxiedClient("api") | ||
| val response = withRetry(3, stopIf = { false }) { | ||
| client.post("https://stripchat.com/api/front/show/models/$roomId/groupShows/${user.userId}") { | ||
| client.post("https://poplive.xyz/api/front/show/models/$roomId/groupShows/${user.userId}") { |
| return sb.toString() | ||
| } | ||
|
|
||
| fun snapshotRoomDetailedStatus(): Map<Long, Map<String, Any>> = |
There was a problem hiding this comment.
再考虑一下,不要绕开EventBus,这点消息量完全处理的过来
| } | ||
| } else { | ||
| logger.debug("Recording stopped for room {}", event.roomId) | ||
| logger.info( |
There was a problem hiding this comment.
这里当时设计的是让Scheduler启动一次录制会话(Session),只要Scheduler没说停止录制Session就应该一直尝试去录制。
也就是说,Session要自己维护一个状态机,处理好启动失败时候的重试。如果session决定不再重试了,要告诉Scheduler,不然Scheduler会认为Session依然在录制。
| if (existing != null) { | ||
| val blocked = when (existing.state) { | ||
| SessionState.Fetching, SessionState.Recording -> true | ||
| SessionState.Fetching -> { |
There was a problem hiding this comment.
这算一个防止重复启动的逻辑,并不确定上层是否会同时启动两次。
这里只需要确保一次startSession中,state一定会从Fetching迁移到Recording或者Closing即可,不需要在第二次调用的时候停止第一次的
|
|
||
| try { | ||
| const res = await fetch(`https://zh.xhamsterlive.com/api/front/v1/broadcasts/${modelName}`); | ||
| const res = await fetch(`https://poplive.xyz/api/front/v1/broadcasts/${modelName}`); |
| # https://stripchat.com/modelA q:720p limit:120 | ||
| ; https://stripchat.com/modelB q:240p | ||
| https://stripchat.com/modelC q:highest | ||
| # https://poplive.xyz/modelA q:720p limit:120 |
There was a problem hiding this comment.
如果改了这里,注意Bootstrap组件加载房间的时候会不会有问题
There was a problem hiding this comment.
但本来项目就是为了xhamster写的,我觉得不改README比较好
Summary
Clean PR from the
sheepweb/XhRecfork. Cherry-picked 7 business commits fromorigin/main, excluding CCG tooling commits.Commits
Changes
9 source files, +118 / −16 — all under
src/:Verification
upstream/main(3a30f4a) — 7 commits cherry-picked cleanly.ccg/directory excluded (zero .ccg paths in diff)./gradlew test— EventBusTest included in this change set