mirror of
https://github.com/zvx-echo6/meshai.git
synced 2026-08-26 17:31:34 +00:00
The ReminderScheduler is the third fire-broadcast exit and the only one
that does not pass through the EventBus, so FirePacer (which paces the
Central and native fire-event exits to <=1/60s) never sees it. Its tick
is a roll-call: every eligible row is its own broadcast, dispatched in a
plain `for` loop with no gap. Unpaced, N eligible fires produce N
back-to-back mesh transmissions; the only downstream protection is
RadioSendQueue's ~2.2-2.6s per-transport inter-packet jitter, which
prevents packet collision but still lets a roll-call monopolise the mesh.
Not currently firing in production (every overdue fire is filtered by
terminate_when, so the eligible set is 0) -- this is fire-season
hardening against a latent burst, not a live incident.
Adds `spacing_seconds` (adapter_config, default 60 to match FirePacer)
enforcing a minimum gap between consecutive SUCCESSFUL reminder
deliveries. Deliberately a pure spacing change:
* WHAT gets broadcast is untouched; nothing is dropped.
* The ok-gated last_broadcast_at stamp still uses the tick's `now`.
* A failed dispatch sent no packet, so it does not arm the gap.
* Rows filtered by terminate_when/render never burn a spacing slot.
* A lone eligible fire has nothing to pace against -> zero added latency.
* The wait is interruptible by stop(): a 15-fire roll-call holds
tick_once() for ~14 min and stop() awaits the tick task, so a plain
sleep would stall shutdown.
Chose in-loop spacing over routing reminders through FirePacer itself:
reminders re-derive their targets from live DB state every tick and only
clear a row via last_broadcast_at after a confirmed send, so enqueuing
into a 60s-drain FIFO would re-enqueue the same fire on every intervening
tick -- the queue would grow faster than it drains. pacer.py, consumer.py,
store.py and main.py are untouched.
Tests fake the clock end-to-end, so 60s spacing costs the suite nothing.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
||
|---|---|---|
| .. | ||
| adapter_config | ||
| backends | ||
| central | ||
| cli | ||
| commands | ||
| dashboard | ||
| data | ||
| env | ||
| notifications | ||
| persistence | ||
| scripts | ||
| sources | ||
| transport | ||
| __init__.py | ||
| __main__.py | ||
| alert_engine.py | ||
| central_normalizer.py | ||
| chunker.py | ||
| config.py | ||
| config_loader.py | ||
| connector.py | ||
| context.py | ||
| coverage.py | ||
| coverage_area.py | ||
| geo.py | ||
| history.py | ||
| knowledge.py | ||
| main.py | ||
| memory.py | ||
| mesh_data_store.py | ||
| mesh_health.py | ||
| mesh_models.py | ||
| mesh_reporter.py | ||
| mesh_sources.py | ||
| meshmonitor.py | ||
| responder.py | ||
| router.py | ||
| secrets_store.py | ||
| serial_ports.py | ||