Backfill: back off retries for a strap with a future-dated clock (#160)#11
Closed
digitalerdude wants to merge 2 commits into
Closed
Backfill: back off retries for a strap with a future-dated clock (#160)#11digitalerdude wants to merge 2 commits into
digitalerdude wants to merge 2 commits into
Conversation
…nbr#160) A strap whose RTC reads future-dated (#928) still banks REAL rows on every backfill pass, so it never trips the existing empty-streak backoff — but #1012 already refuses to trust that range past one pass per connection, so the automatic retries get near-zero value while still costing BLE airtime. Reported as ryanbr#160 ("HR not displaying while band is active"): the user's own connection log showed backfill sessions kicking off every 10-40s on a strap logging exactly this future-dated-clock warning, with live REALTIME_DATA frames only appearing in the last ~10s of a 9-minute capture. Folds the already-tracked future-dated signal into BackfillPolicy's existing empty-streak backoff shape (maxed immediately, since there's no "streak" to build for a clock fault) so .strap/.periodic retries on a known-bogus-clock strap stop competing with realtime HR streaming for the link as often. .connect/.foreground/.manual/.autoContinue stay un-floored, matching how emptyStreak already treats them. This mitigates one contributing factor; it does not touch the deeper BLE reconnect/radio-arbitration behavior (a ryanbr#80-style marginal-radio loop is the likely proximate cause of the reconnect churn itself), which needs real-hardware verification I can't do here.
5 tasks
Owner
Author
|
Closing this fork-internal PR to declutter — the real submission lives at ryanbr/noop (upstream). See that repo's PR list for the current, actionable version of this work. |
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
Toggle Realtime HRcycled off/on every 10-40s, each cycle paired with a freshBackfill: session started. LiveREALTIME_DATA/REALTIME_RAW_DATAframes only appeared in the last ~10s of the whole capture before being cut off again. The strap's own RTC was reporting a time 7868h-28445h ahead of the wall clock throughout — the known #928 future-dated-clock fault.beginBackfill()itself never touches realtime HR. The toggle-off/toggle-on pairing comes from the once-per-BLE-connection handshake, which only replays on an actual disconnect — so its ~10-40s repetition points at the link itself reconnecting that often, most plausibly the existing#80marginal-radio "arm → die → rescan → arm → die" loop (its documented ~20s window matches the observed cadence), aggravated by realtime streaming and historical-offload traffic competing for the same link with nothing today keeping them apart.#1012already caps a future-dated strap's auto-continue chain to one pass per connection, butBackfillPolicy(the baseline.periodic/.strap/.connectrate limiter) has no clock-health awareness at all — and because a future-dated strap still banks real (if mis-dated) rows each pass, it never trips the existing empty-streak backoff either. So it gets the exact same retry cadence as a perfectly healthy strap, generating extra BLE traffic on every reconnect that plausibly feeds back into the radio instability.BackfillContinuation.isFutureDatedNewest, existing #1012 machinery) intoBackfillPolicy.shouldRun's existing empty-streak backoff shape, so.strap/.periodicretries back off immediately for a known-bogus-clock strap..connect/.foreground/.manual/.autoContinuestay un-floored, matching howemptyStreakalready treats them.Test plan
BackfillPolicy.shouldRun) verified against the exact production file content (workaround for a pre-existing, unrelatedStrandTestsTEST_HOST/PRODUCT_NAMEmismatch in this environment that blocks running the Xcode test target directly): all newclockUntrustedcases pass, plus regression checks that every existing case is unchanged.StrandTests/BackfillPolicyTests.swiftcoverage mirroring the existingemptyStreaktests: backs off.strap/.periodicwith no empty streak, doesn't stack past the existing 4x cap, and never delays.connect/.foreground/.manual/.autoContinue.Strand) and iOS (NOOPiOS) targets both build clean viaxcodebuild.docs/CONTRIBUTING.md's own checklist, BLE-path changes need real-strap verification beyond "builds and unit tests pass" — I don't have a WHOOP strap in this environment. This should be confirmed on the reporter's WHOOP 4.0 (or another future-dated-clock strap) before merge.🤖 Generated with Claude Code