prop/test/microwaveprop/weather
Graham McIntire 1ec10bec1f
Split ERA5 backfill into submit/poll workers with persistent CDS state
The single Era5MonthBatchWorker pinned an Oban slot for the full 30-45
min a CDS month-tile takes to assemble, and lost the work entirely on a
rolling deploy because the in-flight Task died with the pod. This splits
the flow into two tiny workers and persists the CDS job IDs so deploys
survive.

New pipeline:

1. Era5SubmitWorker (:era5_submit queue) — POSTs both CDS requests in
   parallel, writes an `era5_cds_jobs` row with the returned job IDs,
   and enqueues an Era5PollWorker scheduled +5 min. ~1s of real work.
   Short-circuits when the month-tile is already cached or when a row
   already exists (in-flight from a previous attempt).

2. Era5PollWorker (:era5_poll queue) — reads the row, calls
   Era5Client.check_status/1 for both CDS job IDs, and:
     - returns {:snooze, 300} if either job is still running (Oban
       re-schedules without counting an attempt and releases the slot
       immediately — a pod can keep dozens of tile-months in flight
       without pinning workers)
     - streams both GRIB files to disk via Req into: File.stream!,
       decodes via Wgrib2.extract_grid_messages_from_file, bulk-inserts
       via Era5BatchClient.decode_and_insert/6, deletes the row, and
       DELETEs both completed jobs from CDS to free server-side quota
     - if either leg CDS-reports failed, deletes the row + both CDS
       jobs and returns {:error, reason}

Era5Client gains four testable building blocks:
  submit_job/2               (bare POST → {:ok, job_id})
  check_status/1             (GET → :running | {:done, src} | {:failed, reason})
  download_source_to_file/3  (streams {:url, href} or writes {:body, bin})
  delete_job/1               (DELETE /jobs/:id, treats 200/202/204/404 as :ok)

All Req calls now route through `era5_req_options` so tests can stub
CDS responses via Req.Test.stub(Era5Client, fn).

Era5MonthBatchWorker is retained as a thin forwarder to Era5SubmitWorker
so any jobs already in the :era5_batch queue on prod pods drain cleanly
on the next rolling deploy. Safe to delete in a follow-up.

Adds era5_cds_jobs table with a unique index on
(year, month, tile_lat, tile_lon) so duplicate submits collapse.

New queue config in runtime.exs:
  era5_submit: local_limit 4, rate_limit 30/hour (burst protection)
  era5_poll:   local_limit 20 (polls are cheap GETs)
  era5_batch:  kept at 1 for legacy job drain, delete next cycle
2026-04-13 16:26:26 -05:00
..
grib2 Fix all remaining credo --strict issues (0 issues) 2026-04-12 10:26:53 -05:00
era5_batch_client_test.exs Wire NEXRAD, native ducts, and commercial links into scoring 2026-04-13 12:08:15 -05:00
era5_cds_job_test.exs Split ERA5 backfill into submit/poll workers with persistent CDS state 2026-04-13 16:26:26 -05:00
era5_client_test.exs Split ERA5 backfill into submit/poll workers with persistent CDS state 2026-04-13 16:26:26 -05:00
frontal_analysis_test.exs Fix credo warnings: struct specs, length/1, and test patterns 2026-04-12 10:26:53 -05:00
grid_cache_test.exs Cache /weather grid, defer contact show mount, cache stats 2026-04-12 12:55:50 -05:00
hrrr_client_test.exs Add HRRR batch fetch client with multi-point grid extraction 2026-03-30 17:08:21 -05:00
hrrr_native_client_test.exs Phase 9.3, 9.4, and Phase 3 NEXRAD pipeline 2026-04-10 12:48:36 -05:00
hrrr_native_profile_test.exs Phase 9.3, 9.4, and Phase 3 NEXRAD pipeline 2026-04-10 12:48:36 -05:00
hrrr_profile_test.exs Partition hrrr_profiles by valid_time for query performance 2026-04-01 11:03:33 -05:00
iem_client_test.exs Add Tier 2 test coverage: SolarIndexWorker, HrrrFetchWorker, IemClient 2026-04-06 10:15:38 -05:00
iemre_observation_test.exs Add IEM precipitation data to QSO weather pipeline 2026-03-30 13:18:11 -05:00
mrms_client_test.exs Add MRMS rain mosaic, fix beacons crash, fix UTC clock flash 2026-04-12 14:49:20 -05:00
ncei_metar_client_test.exs Phase 9.3, 9.4, and Phase 3 NEXRAD pipeline 2026-04-10 12:48:36 -05:00
nexrad_cache_test.exs Add more caching to make the map feel instant 2026-04-12 12:26:25 -05:00
nexrad_client_test.exs Phase 9.3, 9.4, and Phase 3 NEXRAD pipeline 2026-04-10 12:48:36 -05:00
nexrad_observation_test.exs Phase 9.3, 9.4, and Phase 3 NEXRAD pipeline 2026-04-10 12:48:36 -05:00
solar_client_test.exs Add QSO import, solar indices, Oban workers, LiveView UI, and parallel weather import 2026-03-29 13:04:55 -05:00
sounding_params_test.exs Fix credo warnings: struct specs, length/1, and test patterns 2026-04-12 10:26:53 -05:00
sounding_test.exs Add weather data schema, context, sounding params, and IEM ingestion 2026-03-28 15:57:19 -05:00
station_test.exs Add weather data schema, context, sounding params, and IEM ingestion 2026-03-28 15:57:19 -05:00
surface_observation_test.exs Add IEM precipitation data to QSO weather pipeline 2026-03-30 13:18:11 -05:00
theta_e_test.exs Phase 2 tasks 2.1-2.4: BL turbulence feature computations 2026-04-10 08:21:23 -05:00
uwyo_sounding_client_test.exs Ingest Canadian radiosondes via UWYO + plans for RDPS/HRDPS 2026-04-13 09:14:34 -05:00
weather_layers_test.exs Add WeatherLayers module for deriving upper-air map fields from HRRR profiles 2026-04-03 16:49:17 -05:00