Make the live-run mirror survive lost phone-to-watch frames
Live frames ride sendMessage, which is reachable-only — and phone→watch reachability drops exactly when the user is swiping on the phone (wrist down). A frame that failed to send was staged but never retried until a reachability edge, and a frame lost outright desynced the run until the next human transition — sometimes forever, since a reconnect could even re-send the stale staged frame and yank the peer backwards. Four fixes, symmetric on both bridges and both run screens: - A send that fails while nominally reachable now retries with a short backoff (a few times per staged message) instead of being swallowed. - Receiving a frame that outranks the staged outbound one drops the staged frame, so a reconnect re-send can't move the run backwards; a delivery the staged frame outranks is ignored as stale. - Every staleness comparison now tie-breaks the shared version sequence on the frame's wall-clock anchor (LiveProgress.isNewer) — after a lost frame both devices can mint the same version, and the later human action must win. - Durable repair: when the absorbed workout doc shows sets completed beyond anything the open run screen recorded or followed, it jumps forward to the first unfinished set's work page — a lost frame now degrades to a briefly-stale page instead of a stuck one.
This commit is contained in:
@@ -34,9 +34,9 @@ final class LiveRunState {
|
||||
return c
|
||||
}
|
||||
|
||||
/// Apply an incoming frame, dropping a stale one for the same run.
|
||||
/// Apply an incoming frame, dropping a stale (or redelivered) one for the same run.
|
||||
func apply(_ frame: LiveProgress) {
|
||||
if let c = current, c.logID == frame.logID, frame.version < c.version { return }
|
||||
if let c = current, c.logID == frame.logID, !frame.isNewer(than: c) { return }
|
||||
current = frame
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user