ScheduledMessageQueue class final

Constructors

ScheduledMessageQueue({required ExecutionEnv env, required MessagingRepository repo(), required String root(), String selfMailbox()?, String ownerPrefix()?, DateTime clock()?, void onScheduled(String text)?, void onFired(String text)?, void onError(String text)?, Duration failureBackoff = maxTimerLeg, ScheduledReceiptLog? receipts})

Properties

failureBackoff → Duration
Wait before retrying a pass that just failed (issue #270).
final
hashCode → int
The hash code for this object.
no setterinherited
onError → void Function(String text)?
Host-visible notice when a delivery fails (issue #270).
final
onFired → void Function(String text)?
Host-visible notice when a record fires ('fired: <text>').
final
onScheduled → void Function(String text)?
Host-visible notice when a record is scheduled ('in 25m: <text>').
final
receipts → ScheduledReceiptLog?
The persisted receipt trail (gh-1180 AC4), when the host wires one: scheduled / delivered / delivery_failed / scan_failed events keyed by record id. Best-effort — a failing trail never breaks scheduling.
final
runtimeType → Type
A representation of the runtime type of the object.
no setterinherited

Methods

deliverDue() → Future<int>
Delivers every due record. Returns how many were delivered.
dispose() → void
Cancels the armed delivery timer (host teardown) and releases ownership of my pending self-addressed records (their owner tag is cleared, fire-and-forget): a torn-down session is DEAD, and #59's contract is that a fresh session taking over adopts its reminders — while #88's anti-theft tagging protects only LIVE foreign owners. Pending record files stay put either way — they are the source of truth; a later start (host restart, session switch) re-arms and delivers them.
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
pendingRecords() → Future<List<({int? dueMs, String text})>>
Every deliverable pending record with its due time (epoch ms, null when unknown) and text preview — the raw view behind pendingSummary and the CLI's visible-waiting row (issue #450). Same deliverability rule as the timer: foreign-owned self-addressed records are not ours to fire, so they are not ours to show either. Tolerant by contract (indicator-only consumers): a scan failure reads as "nothing pending" here — the ARMING path uses the throwing _scanPending instead, so a scan failure re-arms loudly instead of disarming (gh-1180 AC5). Corrupt records arm no timer and light no indicator.
pendingSummary() → Future<({int count, int? nextDueMs})>
The pending records this instance can still deliver: how many, and the earliest due time (epoch ms; null: none). Same deliverability rule as the timer — foreign-owned self-addressed records are not ours to fire, so they are not ours to show either. Powers the CLI's scheduled-follow-ups indicator (issue #115).
schedule({required String text, required Duration delay, String? to, String? from}) → Future<String>
Persists a delayed message and arms the timer. Returns the record id.
start() → Future<void>
Scans pending records and arms the nearest-due timer. Safe to call repeatedly (idempotent re-arm). Best-effort like mailbox registration: an unwritable messages root disables scheduling instead of crashing startup.
toString() → String
A string representation of this object.
inherited

Operators

operator ==(Object other) → bool
The equality operator.
inherited

Static Methods

formatDelay(Duration d) → String
Compact human delay: 90s / 25m / 2h / 1d.

Constants

maxTimerLeg → const Duration
The longest single timer leg (issue #259). A one-shot timer armed for the full wait freezes with OS sleep (monotonic clocks pause while the lid is closed) and fires late by the slept duration. Capping each leg turns long waits into a lightweight idle heartbeat: every leg's fire recomputes the remaining delay from the WALL clock (_now) — never accumulating duration-based drift — so the first post-sleep fire immediately sees and delivers every overdue record.