fix: a show UI that falls behind the state feed skips frames instead of freezing - #121
Merged
Merged
Conversation
…eezing The show UI renders whatever the brain's 60fps state feed hands it. Nothing bounded that feed per client: a client that could not keep up (or a page the compositor was not painting) accumulated frames in its socket, so it rendered seconds-old state on a connection that looked perfectly healthy — no stale-feed watchdog, no reconnect, nothing but quitting the app to fix it. That is the inner show UI going static while the rig, and every other client, ran on. Two halves: state frames now go out lossily (a client past the backlog limit skips the frame, since the next one supersedes it), and a hidden page drops its socket and takes a fresh one on return rather than queueing a feed nobody can see.
Contributor
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Chasing "the inner show UI stopped updating while the rig and the phone kept running, and only quitting the app fixed it". #114 removed one cause (a throwing
sendaborting the whole broadcast loop). This is the other one it left: the state feed had no per-client bound.broadcastState()runs at 60fps for every client.ws.sendbuffers rather than blocks, so a client that cannot drain that fast — an embedded page the compositor isn't painting, a busy renderer — accumulates frames in its socket. It then renders state that is seconds old while messages keep arriving, so nothing looks wrong: the socket isOPEN, the stale-feed watchdog never trips, no reconnect happens, and there is no recovery short of a new connection. Exactly the reported symptom, and exactly why the outer Nova panel was unaffected — it never went through this feed.Server. State frames are superseded by the next one, so they are now sent lossily:
Only
broadcastStateuses it. Commands, orientation, playlist and config-sync stay on reliablefanout— those are events, not a feed, and must not be dropped.Client. A hidden page can't paint the feed and its timers are throttled, so it was the most reliable way to build that backlog.
useSocketnow closes onvisibilitychange → hiddenand takes a fresh connection on return (suspendeddistinguishes that from a break, soonclosedoesn't schedule a reconnect into a hidden page). Returning to the show route therefore shows the present, not a queue.Honest scope
This is a mechanism that provably produces the symptom, fixed from code reading — not a captured reproduction of the incident. Whether the embedded
WebContentsViewreportsvisibilityState: 'hidden'when the desktop shell hides it is the one assumption worth confirming on the show machine; if it doesn't, the server-side half still bounds the damage.Link to Devin session: https://app.devin.ai/sessions/ec43152136134467a853ec0bbf783ea9
Requested by: @pyramation