prop/lib/microwaveprop/workers/backfill_enqueue_worker.ex
Graham McIntire e99e585b66 Add type filter to backfill enqueue
Backfill dashboard now has checkboxes to select which enrichment types
to process (HRRR, Weather, Terrain, IEMRE). Prevents weather jobs from
flooding the queue when only HRRR needs work.
2026-04-06 11:42:26 -05:00

57 lines
1.6 KiB
Elixir

defmodule Microwaveprop.Workers.BackfillEnqueueWorker do
@moduledoc """
Runs backfill enrichment enqueue as an Oban job so the backfill dashboard
returns immediately instead of blocking on the enqueue loop.
"""
use Oban.Worker, queue: :backfill_enqueue, max_attempts: 1
import Ecto.Query
alias Microwaveprop.Radio.Contact
alias Microwaveprop.Repo
alias Microwaveprop.Workers.ContactWeatherEnqueueWorker
require Logger
@enrichable [:pending, :queued, :failed]
@valid_types ~w(hrrr weather terrain iemre)
@impl Oban.Worker
def perform(%Oban.Job{args: %{"limit" => limit} = args}) do
types = parse_types(args)
contacts =
Contact
|> where([c], not is_nil(c.pos1) or not is_nil(c.grid1))
|> where(^type_filter(types))
|> order_by([c], desc: c.qso_timestamp)
|> limit(^limit)
|> Repo.all()
count = length(contacts)
Logger.info("BackfillEnqueue: processing #{count} contacts (types: #{inspect(types)})")
Enum.each(contacts, &ContactWeatherEnqueueWorker.enqueue_for_contact(&1, types))
Phoenix.PubSub.broadcast(
Microwaveprop.PubSub,
"backfill:enqueue_complete",
{:enqueue_complete, count}
)
:ok
end
defp parse_types(%{"types" => types}) when is_list(types) do
types |> Enum.filter(&(&1 in @valid_types)) |> Enum.map(&String.to_existing_atom/1)
end
defp parse_types(_), do: [:hrrr, :weather, :terrain, :iemre]
defp type_filter(types) do
Enum.reduce(types, dynamic(false), fn type, acc ->
field = :"#{type}_status"
dynamic([c], ^acc or field(c, ^field) in ^@enrichable)
end)
end
end