- Replace stub propagation.ex with real implementation (score_grid_point, upsert_scores, latest_scores, latest_valid_time) - Add PropagationGridWorker (hourly Oban cron) for CONUS grid scoring - Add mix propagation_grid task for manual triggering - Fix duplicate extract_grid/2 from parallel merges - Fix extract_grid to skip outside-grid points instead of erroring - Add propagation queue to Oban config
64 lines
1.9 KiB
Elixir
64 lines
1.9 KiB
Elixir
defmodule Microwaveprop.Workers.PropagationGridWorker do
|
|
@moduledoc """
|
|
Hourly Oban worker that downloads the latest HRRR data and computes
|
|
propagation scores across the CONUS grid for all bands.
|
|
"""
|
|
|
|
use Oban.Worker,
|
|
queue: :propagation,
|
|
max_attempts: 3,
|
|
unique: [period: 3600, states: [:available, :scheduled, :executing]]
|
|
|
|
alias Microwaveprop.Propagation
|
|
alias Microwaveprop.Propagation.Grid
|
|
alias Microwaveprop.Weather.HrrrClient
|
|
|
|
require Logger
|
|
|
|
@impl Oban.Worker
|
|
def perform(%Oban.Job{}) do
|
|
valid_time = HrrrClient.nearest_hrrr_hour(DateTime.utc_now())
|
|
points = Grid.conus_points()
|
|
|
|
Logger.info("PropagationGrid: fetching HRRR for #{valid_time}, #{length(points)} points")
|
|
|
|
with {:ok, grid_data} <- HrrrClient.fetch_grid(points, valid_time) do
|
|
scores =
|
|
grid_data
|
|
|> Task.async_stream(
|
|
fn {{lat, lon}, profile} ->
|
|
band_scores = Propagation.score_grid_point(profile, valid_time)
|
|
|
|
Enum.map(band_scores, fn result ->
|
|
%{
|
|
lat: lat,
|
|
lon: lon,
|
|
valid_time: valid_time,
|
|
band_mhz: result.band_mhz,
|
|
score: result.score,
|
|
factors: result.factors
|
|
}
|
|
end)
|
|
end,
|
|
max_concurrency: System.schedulers_online() * 2,
|
|
timeout: 30_000
|
|
)
|
|
|> Enum.flat_map(fn
|
|
{:ok, results} -> results
|
|
{:exit, _reason} -> []
|
|
end)
|
|
|
|
Logger.info("PropagationGrid: computed #{length(scores)} scores, upserting")
|
|
|
|
case Propagation.upsert_scores(scores) do
|
|
{:ok, count} ->
|
|
Logger.info("PropagationGrid: upserted #{count} scores for #{valid_time}")
|
|
:ok
|
|
|
|
error ->
|
|
Logger.error("PropagationGrid: upsert failed: #{inspect(error)}")
|
|
error
|
|
end
|
|
end
|
|
end
|
|
end
|