mirror of
https://github.com/Shik3i/KoalaSync.git
synced 2026-08-30 20:49:22 +00:00
fix(sync): close canonical recovery merge blockers
This commit is contained in:
+14
-4
@@ -41,8 +41,10 @@ not. Heartbeats remain observational and do not mutate canonical state.
|
||||
|
||||
`ROOM_DATA` materializes the playing position at snapshot creation and advertises
|
||||
the optional `media-state-v1` capability. A joining/reconnecting client validates
|
||||
the room/revision, respects Host Control solo mode and Episode Lobby, then sends an
|
||||
internal `APPLY_CANONICAL_MEDIA_STATE` message to the existing content/video path.
|
||||
the room/revision and optional privacy-sanitized media title, respects Host Control
|
||||
solo mode and Episode Lobby, then queues an internal
|
||||
`APPLY_CANONICAL_MEDIA_STATE` message on the same ordered content path as newer
|
||||
live commands.
|
||||
That path reuses frame election, Netflix/Disney page-API seeks, native play/pause,
|
||||
the 2-second drift tolerance, and programmatic-event suppression. Recovery only
|
||||
completes after playback state and position verification. Transient failures
|
||||
@@ -52,10 +54,18 @@ snapshot advances from its local receipt time while waiting for a target, and
|
||||
the apply creates no action history, notification, command ACK, or relay media
|
||||
event.
|
||||
|
||||
Current clients announce `media-state-v1` as an optional client capability and
|
||||
continue sending accepted media controls while alone on a capable relay. If a
|
||||
room instead falls back to one legacy client that suppresses solo controls, the
|
||||
relay clears canonical state so a future joiner receives no snapshot rather than
|
||||
known-unreliable playback truth.
|
||||
|
||||
Force Sync remains a two-phase ACK protocol. A valid `PREPARE` is temporary
|
||||
room-wide choreography; the next authorized `EXECUTE` commits the latest target
|
||||
visible to peers to canonical state before the relay target TTL. That TTL is
|
||||
longer than the client ACK timeout so its scheduled fallback can still land. The
|
||||
visible to peers to canonical state. Delayed execution is logged but remains
|
||||
valid until newer accepted playback or lobby state explicitly supersedes it; an
|
||||
untracked post-restart execute retains legacy relay liveness without inventing a
|
||||
canonical target. The
|
||||
offline queue replays an adjacent `PREPARE`/`EXECUTE` pair in one paced batch and
|
||||
retains both if delivery fails. Per-sender
|
||||
`seq`, peer heartbeats, and the reconnect queue remain separate mechanisms. The
|
||||
|
||||
+20
-12
@@ -54,7 +54,7 @@ Payload:
|
||||
"password": "string, max 128, optional",
|
||||
"tabTitle": "string, max 100, optional",
|
||||
"mediaTitle": "string, max 100, optional",
|
||||
"clientCapabilities": ["chat-v1"],
|
||||
"clientCapabilities": ["chat-v1", "media-state-v1"],
|
||||
"protocolVersion": "string, max 16"
|
||||
}
|
||||
```
|
||||
@@ -110,8 +110,9 @@ The internal `currentTime` is the media position at server-owned `updatedAt`.
|
||||
Playing state advances lazily when a snapshot is requested; paused state stays
|
||||
fixed. `revision`, `updatedAt`, and `updatedBy` are server-owned. Clients cannot
|
||||
spoof them. The wire snapshot contains the already-projected `currentTime`,
|
||||
`revision`, `playbackState`, and `updatedBy`, so clients never compare client and
|
||||
server wall clocks.
|
||||
`revision`, `playbackState`, `updatedBy`, and an optional privacy-sanitized
|
||||
`mediaTitle`, so clients never compare client and server wall clocks and retain
|
||||
the existing cross-episode guard during recovery.
|
||||
|
||||
Only accepted, sanitized room controls update canonical state:
|
||||
|
||||
@@ -121,11 +122,12 @@ Only accepted, sanitized room controls update canonical state:
|
||||
established playback state.
|
||||
- a valid `force_sync_prepare` records only temporary coordination state. The
|
||||
next authorized `force_sync_execute` commits the latest room-wide prepared
|
||||
target as playing before `FORCE_SYNC_TARGET_TTL` expires. This relay TTL is
|
||||
intentionally longer than the client's `FORCE_SYNC_TIMEOUT` ACK wait so the
|
||||
normal timeout fallback remains deliverable. Expired targets are cleared and
|
||||
cannot alter canonical state. The latest valid prepare is also the only
|
||||
post-demotion execute exemption in Host Control mode.
|
||||
target as playing. A target older than `FORCE_SYNC_TARGET_DELAY_WARNING` is
|
||||
logged but remains executable until newer room playback supersedes it, because
|
||||
receivers are already paused. An execute without retained target still uses
|
||||
the legacy wire fallback after relay restart but cannot invent canonical state.
|
||||
The latest valid prepare is also the only post-demotion or reconnect execute
|
||||
exemption in Host Control mode.
|
||||
|
||||
`peer_status` heartbeats are observations and never rewrite canonical intent.
|
||||
For current clients, the relay drops invalid, duplicate, or regressing `seq`
|
||||
@@ -152,7 +154,12 @@ relaying the established event names, payloads, and order unchanged. This makes
|
||||
server-first rollout safe: old clients populate recovery state without needing to
|
||||
understand or acknowledge it, and new clients consume it only when the relay
|
||||
advertises the capability. No protocol-version or minimum-version bump is
|
||||
required. Offline `play`/`pause`/`seek` compaction remains the separate
|
||||
required. New clients also announce `"media-state-v1"` in optional
|
||||
`join_room.clientCapabilities`; this only tells a capable relay that the client
|
||||
keeps canonical state current while alone. When a room falls back to one legacy
|
||||
client, the relay clears potentially stale canonical state instead of recovering
|
||||
future joiners to unverified solo playback. Offline `play`/`pause`/`seek`
|
||||
compaction remains the separate
|
||||
client-owned layer described below rather than part of the relay capability.
|
||||
|
||||
### Offline media intent
|
||||
@@ -347,9 +354,10 @@ The current extension sends sequence/action metadata but no target; the relay us
|
||||
the latest validated room target retained from `force_sync_prepare`. In
|
||||
`host-only` mode, only controllers may send it.
|
||||
The relay also allows that latest valid initiator's execute event after their
|
||||
controller state changed before execute. Invalid prepares are dropped and grant
|
||||
no exemption. The retained target expires after `FORCE_SYNC_TARGET_TTL`, which
|
||||
includes a relay grace period beyond the client's ACK timeout.
|
||||
controller state changed or their socket reconnected before execute. Invalid
|
||||
prepares are dropped and grant no exemption. Newer accepted playback/lobby state
|
||||
explicitly supersedes the prepared target, so its delayed execute is dropped.
|
||||
Otherwise, even a delayed execute is relayed to release paused receivers.
|
||||
|
||||
## Episode Lobby
|
||||
|
||||
|
||||
Reference in New Issue
Block a user