Repository navigation
Decide a client's availability and its join in the session - #98
Merged
Merged
Conversation
A client's `available` and the join a turn to `available: true` makes for its stream roles were tracked in PlayerStream, whatever the client's roles, and ServerCore read them as the player's. Session now tracks them and sets the join for both stream roles; PlayerStream and VisualizerStream keep only their own copy for eligibility, and ServerCore reads the session's. A Session test covers which reports are a join, and a raw-client test has a visualizer-only client that starts unavailable in a playing group join it at the group lead once it reports available.
Contributor
There was a problem hiding this comment.
🟢 Approval recommended
The focused refactor preserves existing semantics, updates the affected caller, and adds regression coverage with no identified blocking issues.
0 open findings
What changed in this PR
Moves client availability and availability-triggered joins into Session, preserving behavior while clarifying ownership for visualizer-only clients.
Changes:
- Centralizes availability tracking and join decisions in
Session. - Removes session-wide availability responsibilities from
PlayerStream. - Adds session regression coverage and a visualizer integration test.
| File | Description |
|---|---|
| tests/test_session.cpp | Tests availability transitions and join decisions. |
| tests/test_server_visualizer.cpp | Tests availability-driven startup and shares timing assertions. |
| src/session.h | Adds session availability state and accessor. |
| src/session.cpp | Decides availability-triggered joins. |
| src/server_core.cpp | Reads availability directly from the session. |
| src/player_stream.h | Removes the availability accessor and redundant tracking field. |
| src/player_stream.cpp | Limits join decisions to the role’s first state object. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
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
A client's
availableand the join a turn toavailable: truemakes for its stream roles lived inPlayerStream, whatever roles the client had, andServerCoreread them assession().player().available(). That placement made a visualizer-only client's join look missing. It was not:PlayerStreamset the join for every client, andSessionapplies the kind to both stream roles. This moves the decision to the session, where it belongs. Behavior is unchanged.Change
Session::on_client_statedecides the join: a report ofavailable: truethat is the first or followsfalse.Session::available()exposes the latest report.PlayerStreamdrops itsstate_received_, its availability join and itsavailable()accessor. Itson_client_statereturns a kind only for the role's first object since its activation, asVisualizerStream's does.PlayerStreamandVisualizerStreameach keep their copy ofavailablefor eligibility, asArtworkStreamandSourceStreamdo.ServerCore::on_client_statereadssession().available().on_activation_written()bodies. The visualizer's also resets itsoffset_.Tests
SessionTest.MakesATurnToAvailableAJoin: a table overSessionwith no I/O, on a visualizer-only client. Each row's lastclient/statecarries no role object, so any join is availability's. It covers true after false (Control), a first true, true after true, false after true and a first false. The "true after true" row covers the old rule, which had no test.ServerVisualizer.JoinsAPlayingGroupOnceItTurnsAvailable: a visualizer-only client whose firstclient/statereportsavailable: falsestays in the playing group it joined. Once it reportstrue, its stream starts the group lead past itsstream/start. The check of the first message against the lead is shared withStartsAJoinerTheGroupLeadPastItsStart.available: truearrives, so the Session test holds the rule.Closes #26