mirror of
https://github.com/Shik3i/KoalaSync.git
synced 2026-08-30 20:49:22 +00:00
fix(sync): harden canonical recovery
This commit is contained in:
+12
-6
@@ -44,17 +44,23 @@ the optional `media-state-v1` capability. A joining/reconnecting client validate
|
||||
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.
|
||||
That path reuses frame election, Netflix/Disney page-API seeks, native play/pause,
|
||||
the 2-second drift tolerance, and programmatic-event suppression. The apply is
|
||||
one-shot recovery: a pending playing 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.
|
||||
the 2-second drift tolerance, and programmatic-event suppression. Recovery only
|
||||
completes after playback state and position verification. Transient failures
|
||||
retry after 250, 750, 1500, and 3000 ms, while target, heartbeat, and content-boot
|
||||
signals can retrigger a pending attempt within that bound. A pending playing
|
||||
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.
|
||||
|
||||
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 shared Force Sync timeout. The
|
||||
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
|
||||
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.
|
||||
`seq`, peer heartbeats, and the reconnect queue remain separate mechanisms. The
|
||||
relay rejects duplicate/regressing current-client media sequences before they
|
||||
can diverge canonical truth from live receivers.
|
||||
|
||||
## 3.2 Offline Media Intent
|
||||
|
||||
|
||||
+18
-10
@@ -121,21 +121,28 @@ 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_TIMEOUT` expires. 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 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.
|
||||
|
||||
`peer_status` heartbeats are observations and never rewrite canonical intent.
|
||||
Per-sender `seq` still orders commands from one sender; canonical `revision`
|
||||
orders server-accepted room transitions. Neither replaces the other.
|
||||
For current clients, the relay drops invalid, duplicate, or regressing `seq`
|
||||
values on room-moving media commands before relay/canonical mutation. Legacy
|
||||
clients without `seq` retain their existing behavior. Canonical `revision`
|
||||
orders server-accepted room transitions; it does not replace per-sender order.
|
||||
|
||||
On join/reconnect, a capable extension applies a valid snapshot once through an
|
||||
extension-internal recovery message. Existing seek/page-API and native-event
|
||||
On join/reconnect, a capable extension attempts to apply a valid snapshot
|
||||
through an extension-internal recovery message. Recovery is only marked handled
|
||||
after playback state and position verification. Transient failures use bounded
|
||||
retries after 250, 750, 1500, and 3000 ms and can also be retriggered by target,
|
||||
heartbeat, or content-boot signals. Existing seek/page-API and native-event
|
||||
suppression prevent `play`, `pause`, or `seek` echoes. Pending recovery is scoped
|
||||
to the room/revision in `chrome.storage.session`, waits for the selected media
|
||||
target lifecycle, and projects a still-playing snapshot from its local receipt
|
||||
time before a delayed apply. It is cleared on leave/switch. Intentional host-only guest
|
||||
desync and an active Episode Lobby take precedence over snapshot recovery.
|
||||
time before a delayed apply. It is cleared on leave/switch. Intentional host-only
|
||||
guest desync and an active Episode Lobby take precedence over snapshot recovery.
|
||||
|
||||
Compatibility is additive: new clients use old behavior with a relay that omits
|
||||
the capability; old clients ignore the extra `room_data` field from a new relay.
|
||||
@@ -341,7 +348,8 @@ 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.
|
||||
no exemption. The retained target expires after `FORCE_SYNC_TARGET_TTL`, which
|
||||
includes a relay grace period beyond the client's ACK timeout.
|
||||
|
||||
## Episode Lobby
|
||||
|
||||
|
||||
Reference in New Issue
Block a user