Repository navigation
Conversation
Keep the early-morning fallback for score-only nights and recheck deferred recaps from WorkManager when no new data arrives. Reuse the existing per-night notification marker across the UI and worker. Refs #2289
6ab5600 to
44ad3e6
Compare
|
Thanks @kavemang. The behaviour is right and the guards are right: One question about the mechanism rather than the outcome. A 15-minute periodic worker for a once-daily event
The guards in val days = app.repository.recentDaysMergedFlow(deviceId).first()
val row = resolveTodayRow(days, logicalDayKeyNow(), LocalDate.now().toString())
if (row?.totalSleepMin != null) { ScheduledReportNotifier.onMorning(...) }So each of those ~96 runs collects a merged-days flow and resolves a row, and about 95 of them can do nothing useful: either it is not yet morning, or the recap for that night has already gone out. On a phone that is also holding a BLE link and running the connection service, that is a cost users of this app do notice; drain reports are a recurring thread here. Your reasoning for polling is sound, and I would keep it rather than coupling the recap to a database write or an open Today screen. It is the unbounded duration I would change. Any of these keeps the decoupling:
The second is the smallest and gets most of it: the same polling shape, but the expensive half only runs while a recap is actually possible. Smaller note
Refs #567 |
Refs #2289 and #567.
Defers the Android morning recap until the recorded main sleep has ended and settled, preserving the once-per-reported-night marker, morning floor and mutex. Score-only imports with no sleep session retain the 05:00 fallback. The periodic fallback remains independent of an open Today screen or a database-write callback.
The refresh worker now checks the opt-in preference, earliest morning minute and already-reported day before collecting merged repository days. It resolves logical and calendar keys from one time snapshot; the marker shortcut applies only when both candidate day keys agree, preserving the local-night rollover case. Normal ineligible runs do no repository work and emit no log.
Refresh exceptions now produce a warning with the error. Coroutine cancellation propagates without a failure log. The existing periodic cadence and completion result are retained, so a failure waits for the next periodic opportunity rather than adding a burst of retries. Existing notifier wake-settle and duplicate-post protection remain authoritative.
Validation: 63 private actual-worker cases passed with Android/WorkManager stubs and an injected clock, covering zero-read guards, morning boundaries, day markers, empty sleep, repository failure logging and cancellation propagation. All 23 existing ScheduledReportPolicy tests passed using the production policy. Comment hygiene, diff-scoped i18n and whitespace passed. Guarded parity regeneration passed (289 known findings); all four expected checks passed at
565d47ff0fb305f653177696ec1c2dc85102fb15: Android APK build and full unit suite, Tools Python, hygiene and i18n. The complete four-check roster and unchanged head were rechecked. The private harness does not establish Android/WorkManager runtime behavior or compile the full app.No Android device notification timing was tested. WorkManager delivery is best effort and may run later than the 15-minute period.