Radar history: capture per location from the IEM archive, with guaranteed lead-in and no dropped frames #210
Labels
No labels
area:ai
area:ci-cd
area:notifications
area:observability
area:public-pages
backlog
bug
duplicate
enhancement
help wanted
invalid
question
security
type:decision
type:feature
type:infra
type:maintenance
type:security
v1.0.1
v1.1.0
v1.2.0
v1.3.0
v2.0.0
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
rbrooks/WeatherBot#210
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?
Decided with @rbrooks on 2026-10-13. Ships in v2.0.0 (@rbrooks's decision). Supersedes the per-alert capture from #130 and the cap discussion on #208. Parent: #22.
Why
Radar frames are captured per alert, live, with a 24-frame cap. That has three weaknesses:
The enabler
Iowa State's archive (IEM) serves the national NEXRAD base-reflectivity mosaic at 5-minute steps for arbitrary past times, with the same bbox request shape used for NOAA:
Measured 2026-10-13 for the Wichita bbox:
Design
Frames belong to a location and a radar time. New table keyed
(location_id, valid_at)on a 5-minute grid. Overlapping alerts share one image.Capture is "fill the window", idempotent. For each location, the wanted slots are the union over its qualifying alerts of
[start − lead-in, end + tail]. The job fetches whichever wanted slots are missing. No per-alert cap; the window bounds the work.Lead-in is retroactive. 60 minutes before first fire, fetched from the archive. Tail is 30 minutes after the alert ends.
Tiers (by NWS event name):
Special Marine, Lake Effect Snow and Storm Surge Warnings were added as siblings of the approved lists.
Nothing dropped:
Scope
0038:location_radar_framesalert_radar_framesfor events that have noneUnchanged
alert_radar_framesrows and files stay readable and keep their retention. Regenerating old events from the archive is a possible follow-up, not part of this.Known trade-offs
0033 → 0038.Merged via #211 (
851b4fe). CI run 261 green in 6m22s: ruff,alembic upgrade headthrough0038on a fresh Postgres, both test tiers,pip-audit, and the image build.Not released or deployed yet;
mainis ahead ofv2.0.0-rc6by this and the #208 cadence fix (which this supersedes: the code it fixed is deleted).Changes made in review beyond the original spec:
RADAR_ARCHIVE_FULL_MAX_HOURS), and alerts whose capped window predates the lookback are skipped, so a dashboard row that never clears cannot drive an endless backfill.Leaving open until verified on dev
Follow-ups not in this change
0033 → 0038.Verified on dev (
2.0.0-rc7), 2026-10-14 00:36–00:50 UTCDeploy: tag
v2.0.0-rc7onfc25cc6, image digestsha256:81645a9a…4fae, pin bump Rhoving/iac-repo#640 (merged as1f430dc), playok=23 changed=3 failed=0. A pre-upgrade dump was taken first:/home/claude/weatherbot-dev-pre-2.0.0rc7-20261014.sql.gzondocker-test(7.6 MB, database at0037).0038applied on a real database:Running upgrade 0037 -> 0038. New table present; the 492 legacyalert_radar_framesrows untouched.wanted=155 missing=155 fetched=120 blank_deferred=0 failed=0(stopped at the 120-per-run budget, 58 seconds). Second run:wanted=157 missing=37 fetched=37. Backlog cleared in two runs, zero failures.get_event_radar_looppath inside the container: Salina 55 frames, 3.58 MB, 9.8 s; Wichita 70 frames, 4.30 MB, 6.8 s. Coverage reads55 of 55and70 of 70.This is also the first real convective radar loop seen in the Explorer, open on #22 since rc3.
Still not verified
blank_deferredstayed 0).Observations
Failed to parse hazard parameters for alert …once a minute for one Oklahoma alert. Fail-soft parsing innws.pythat swallows the exception without logging it.Correction to the disk figure above: I measured 9.4 MB for the first 120 frames (about 78 KB each) and did not re-measure after the second run. "157 frames took 14 MB" was an estimate written as a measurement; at the measured rate 157 frames is about 12 MB.