notify: shared reminder scheduler seam #97
Labels
No labels
adr
android
area/calendar
area/design-system
area/i18n
area/jobs
area/offline
area/server
area/testing
bug
ci
duplicate
enhancement
help wanted
invalid
notifications
question
reliability
security
severity/low
severity/medium
tracking
web
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
eagraiclainne/app#97
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The meal rota reminder (
internal/services/mealrota/reminder.go) is a bespoke daily ticker: wake at 09:00 in the rota's zone, claim the firing with a locked compare-and-set onreminder_last_sent, ring, sleep. It works, and it is about to be copied — #91 (JOB_DUE) needs the same loop keyed on item deadlines, #98 (event reminders) needs it keyed on occurrence dates, and #99 (overdue jobs) extends #91.Three hand-rolled copies of a sleep/claim/fire loop is how the restart-safety and catch-up-after-downtime subtleties drift apart. Extract the shared shape into a seam (
internal/notifyor a sibling package): the generic part owns the clock, the wall-clock wake hour, the cutoff-hour catch-up bound, the claim protocol and the retry pacing; each reminder supplies "what is due today and who hears about it".Scope:
Sequencing: either this lands first and #91 consumes it, or #91 copies the loop and this issue refactors both copies onto the seam afterwards. Landing it first is less total work.
Follow-up from the reminders audit.
Scope note from the #98 decisions (2026-08-16): the seam must support arbitrary next-fire times (per-event lead times), not only a daily wall-clock hour. The generic part becomes "compute next due instant, sleep until it, claim, fire" with the daily-at-09:00 pattern as one consumer shape (meal rota, #91/#99) and instant-based firing as another (#98). Claim/catch-up semantics unchanged.
mainto v1.5.0