defmodule Microwaveprop.Workers.PartitionMaintenanceWorker do @moduledoc """ Daily Oban job that keeps the time-partitioned tables ahead of the current write window. Calls `Microwaveprop.PartitionManager.ensure_quarterly_partitions/1` for the default parents (`hrrr_profiles`, `hrdps_profiles`) with a 4-quarter lookahead. Idempotent — the partition manager uses `CREATE TABLE IF NOT EXISTS`, so a fire that finds nothing missing is a no-op. Lookahead choice: 4 quarters ≈ 1 year of runway. The cron runs daily, so a single missed fire (or a week of missed fires after an outage) still leaves >9 months of partition coverage before writes would hit a missing quarter. The safety margin is intentionally large — the cost of an extra empty partition is one zero-row table, while the cost of a missing partition is silently failed inserts. """ use Oban.Pro.Worker, queue: :admin, max_attempts: 3, unique: [period: 3600, states: :incomplete] alias Microwaveprop.PartitionManager require Logger @lookahead_quarters 4 @impl Oban.Worker @spec perform(Oban.Job.t()) :: :ok def perform(%Oban.Job{args: args}) do lookahead = lookahead(args) results = PartitionManager.ensure_quarterly_partitions(lookahead) created = Enum.filter(results, fn {_, _, status} -> status == :created end) case created do [] -> Logger.info("PartitionMaintenanceWorker: all #{length(results)} partitions already exist") list -> names = Enum.map_join(list, ", ", fn {_parent, name, _} -> name end) Logger.info("PartitionMaintenanceWorker: created partitions: #{names}") end :ok end @spec lookahead(map()) :: non_neg_integer() defp lookahead(%{"lookahead_quarters" => n}) when is_integer(n) and n >= 0, do: n defp lookahead(_), do: @lookahead_quarters end