diff --git a/lib/microwaveprop/workers/propagation_grid_worker.ex b/lib/microwaveprop/workers/propagation_grid_worker.ex index 1b89bf30..21e3cbc2 100644 --- a/lib/microwaveprop/workers/propagation_grid_worker.ex +++ b/lib/microwaveprop/workers/propagation_grid_worker.ex @@ -5,10 +5,12 @@ defmodule Microwaveprop.Workers.PropagationGridWorker do Fetches f00-f18 to provide 18-hour forecast timeline. """ + # `unique.period` matches the 3-hour cron so a retrying job can't be + # duplicated by the next cron firing. use Oban.Worker, queue: :propagation, max_attempts: 3, - unique: [period: 3600, states: [:available, :scheduled, :executing, :retryable]] + unique: [period: 10_800, states: [:available, :scheduled, :executing, :retryable]] alias Microwaveprop.Propagation alias Microwaveprop.Propagation.BandConfig @@ -22,6 +24,16 @@ defmodule Microwaveprop.Workers.PropagationGridWorker do require Logger + # Hard ceiling per run. A healthy run is ~60 min (19 forecast hours × ~3 min + # each). 90 min gives 1.5× headroom and is under the 3-hour cron cadence, so + # a stuck wgrib2/HTTP call can't block the queue indefinitely. Oban kills + # the executing process on timeout, which closes linked ports and cascades + # SIGKILL to any child wgrib2 subprocess. + @run_timeout_ms 90 * 60 * 1000 + + @impl Oban.Worker + def timeout(_job), do: @run_timeout_ms + @max_forecast_hour 18 @impl Oban.Worker