prop/lib/microwaveprop/workers/solar_index_worker.ex
Graham McIntire 16883591b4
Database performance fixes and async backfill enqueue
- Fix score_pressure crash on nil pressure_mb (coastal HRRR points)
- Set 10-min timeout on grid score upsert transaction (was :infinity)
- Single DELETE for prune_old_scores instead of N queries in a loop
- Remove dead load_hrrr_refractivity that loaded 95k rows into nil map
- Pass selected_time to point_detail to skip latest_valid_time sub-query
- Batch station existence checks (1 query per path point, not per station)
- Batch solar index upserts via insert_all in chunks of 500
- Batch backfill_distances via single UPDATE FROM VALUES statement
- Add is_grid_point boolean + partial index to hrrr_profiles (replaces
  non-sargable modular arithmetic filter on every weather map query)
- Add partial index on contacts(qso_timestamp) WHERE pos1 IS NOT NULL
- Move backfill enqueue to Oban worker so UI returns immediately
2026-04-04 19:19:18 -05:00

50 lines
1.2 KiB
Elixir

defmodule Microwaveprop.Workers.SolarIndexWorker do
@moduledoc false
use Oban.Worker,
queue: :solar,
max_attempts: 3,
unique: [period: 300, states: [:available, :scheduled, :executing, :retryable]]
alias Microwaveprop.Weather
alias Microwaveprop.Weather.SolarClient
@impl Oban.Worker
def perform(%Oban.Job{args: %{"date" => date_str}}) do
{:ok, target_date} = Date.from_iso8601(date_str)
case SolarClient.fetch_solar_indices() do
{:ok, all_records} ->
matched = Enum.filter(all_records, fn r -> r.date == target_date end)
Weather.upsert_solar_indices_batch(matched)
if matched != [] do
Phoenix.PubSub.broadcast(
Microwaveprop.PubSub,
"contact_enrichment:solar",
{:solar_ready, date_str}
)
end
:ok
{:error, reason} ->
{:error, reason}
end
end
def perform(%Oban.Job{}) do
since_date = Date.add(Date.utc_today(), -7)
case SolarClient.fetch_solar_indices() do
{:ok, all_records} ->
all_records
|> SolarClient.filter_since(since_date)
|> Weather.upsert_solar_indices_batch()
:ok
{:error, reason} ->
{:error, reason}
end
end
end