Replaces the one-shot startup Task with a GenServer that checks every 5 minutes whether propagation scores are older than 2 hours. If stale, enqueues a PropagationGridWorker job (with dedup check to avoid double queuing). Disabled in test env to avoid SQL Sandbox conflicts.
72 lines
1.8 KiB
Elixir
72 lines
1.8 KiB
Elixir
defmodule Microwaveprop.Propagation.FreshnessMonitor do
|
|
@moduledoc """
|
|
Monitors propagation score freshness and enqueues grid worker jobs
|
|
when data is stale. Checks every 5 minutes. Covers missed cron ticks,
|
|
slow deploys, worker crashes, and any other gap in hourly scoring.
|
|
"""
|
|
|
|
use GenServer
|
|
|
|
alias Microwaveprop.Propagation
|
|
alias Microwaveprop.Workers.PropagationGridWorker
|
|
|
|
require Logger
|
|
|
|
@check_interval :timer.minutes(5)
|
|
@stale_threshold_minutes 120
|
|
|
|
def start_link(_opts) do
|
|
if Application.get_env(:microwaveprop, :start_freshness_monitor, true) do
|
|
GenServer.start_link(__MODULE__, :ok, name: __MODULE__)
|
|
else
|
|
:ignore
|
|
end
|
|
end
|
|
|
|
@impl true
|
|
def init(:ok) do
|
|
send(self(), :check)
|
|
{:ok, %{}}
|
|
end
|
|
|
|
@impl true
|
|
def handle_info(:check, state) do
|
|
check_freshness()
|
|
Process.send_after(self(), :check, @check_interval)
|
|
{:noreply, state}
|
|
end
|
|
|
|
defp check_freshness do
|
|
case Propagation.latest_valid_time() do
|
|
nil ->
|
|
Logger.info("FreshnessMonitor: no scores found, enqueuing grid worker")
|
|
enqueue_if_not_queued()
|
|
|
|
latest ->
|
|
age = DateTime.diff(DateTime.utc_now(), latest, :minute)
|
|
|
|
if age > @stale_threshold_minutes do
|
|
Logger.info("FreshnessMonitor: scores are #{age}m old, enqueuing grid worker")
|
|
enqueue_if_not_queued()
|
|
end
|
|
end
|
|
end
|
|
|
|
defp enqueue_if_not_queued do
|
|
# Only enqueue if there isn't already a pending/running grid worker job
|
|
import Ecto.Query
|
|
|
|
pending =
|
|
Microwaveprop.Repo.exists?(
|
|
from(j in "oban_jobs",
|
|
where:
|
|
j.worker == "Microwaveprop.Workers.PropagationGridWorker" and
|
|
j.state in ["available", "scheduled", "executing"]
|
|
)
|
|
)
|
|
|
|
unless pending do
|
|
Oban.insert(PropagationGridWorker.new(%{}))
|
|
end
|
|
end
|
|
end
|