fix(weather): reconcile_hrrr_statuses also flips OCONUS path points to :unavailable
Root cause of the "81,980 / 81,994" display that wouldn't advance: 14 contacts had pos1 inside the HRRR CONUS grid but pos2 or the great-circle midpoint landed outside it (50°N+ into Canada, mid- Atlantic, Pacific, Caribbean, Alaska). The Rust hrrr-point-worker silently returns no profile for OCONUS points, so `hrrr_data_fully_present?/1` never evaluated true and the contact sat `:queued` forever. The existing ContactWeatherEnqueueWorker.mark_hrrr_status!/3 already flips to `:unavailable` on empty job lists via NarrClient.in_coverage? + Grid.contains?(pos1), but those checks only considered pos1 — not the full contact_path_points list. When pos1 was in-grid but a downstream point was not, the contact entered `:queued` and the reconciler couldn't rescue it. `reconcile_hrrr_statuses/0` now sweeps `:queued` contacts into two buckets: - ANY path point OCONUS → `:unavailable` (matches what the enqueuer would emit had it known about the downstream points); - else, all points present → `:complete`. Applied once in prod to 14 stuck contacts; cron path picks up any new occurrences going forward.
This commit is contained in:
parent
b5c6e30fbf
commit
ea69712bd9
1 changed files with 37 additions and 12 deletions
|
|
@ -3,6 +3,7 @@ defmodule Microwaveprop.Weather do
|
||||||
|
|
||||||
import Ecto.Query
|
import Ecto.Query
|
||||||
|
|
||||||
|
alias Microwaveprop.Propagation.Grid
|
||||||
alias Microwaveprop.Propagation.ProfilesFile
|
alias Microwaveprop.Propagation.ProfilesFile
|
||||||
alias Microwaveprop.Radio
|
alias Microwaveprop.Radio
|
||||||
alias Microwaveprop.Radio.Contact
|
alias Microwaveprop.Radio.Contact
|
||||||
|
|
@ -302,10 +303,19 @@ defmodule Microwaveprop.Weather do
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Flip `contacts.hrrr_status` from `:queued` to `:complete` for every
|
Reconcile `contacts.hrrr_status` for every `:queued` contact:
|
||||||
contact whose HRRR data is fully present (all path points at the
|
|
||||||
rounded HRRR hour and grid cell). Same shape as
|
* flips to `:complete` when every path point has an hrrr_profiles
|
||||||
`reconcile_iemre_statuses/0`.
|
row at the rounded HRRR hour;
|
||||||
|
* flips to `:unavailable` when any path point falls outside the
|
||||||
|
HRRR CONUS grid (pos2 or the great-circle midpoint can drift
|
||||||
|
into Canada, the mid-Atlantic, or the Pacific even when pos1 is
|
||||||
|
stateside — the Rust hrrr-point-worker returns no profile for
|
||||||
|
those points and the contact would otherwise sit `:queued`
|
||||||
|
forever).
|
||||||
|
|
||||||
|
Returns `{:ok, n}` where `n` is the total number of contacts advanced
|
||||||
|
(completed + oconus).
|
||||||
"""
|
"""
|
||||||
@spec reconcile_hrrr_statuses() :: {:ok, non_neg_integer()}
|
@spec reconcile_hrrr_statuses() :: {:ok, non_neg_integer()}
|
||||||
def reconcile_hrrr_statuses do
|
def reconcile_hrrr_statuses do
|
||||||
|
|
@ -316,15 +326,30 @@ defmodule Microwaveprop.Weather do
|
||||||
|> where([c], c.hrrr_status == :queued and not is_nil(c.pos1))
|
|> where([c], c.hrrr_status == :queued and not is_nil(c.pos1))
|
||||||
|> Repo.all()
|
|> Repo.all()
|
||||||
|
|
||||||
to_complete = Enum.filter(queued, &hrrr_data_fully_present?/1)
|
{oconus, rest} = Enum.split_with(queued, &contact_has_oconus_path_point?/1)
|
||||||
|
to_complete = Enum.filter(rest, &hrrr_data_fully_present?/1)
|
||||||
|
|
||||||
if to_complete == [] do
|
_ =
|
||||||
{:ok, 0}
|
if oconus != [] do
|
||||||
else
|
ids = Enum.map(oconus, & &1.id)
|
||||||
ids = Enum.map(to_complete, & &1.id)
|
Radio.set_enrichment_status!(ids, :hrrr_status, :unavailable)
|
||||||
_ = Radio.set_enrichment_status!(ids, :hrrr_status, :complete)
|
end
|
||||||
{:ok, length(to_complete)}
|
|
||||||
end
|
_ =
|
||||||
|
if to_complete != [] do
|
||||||
|
ids = Enum.map(to_complete, & &1.id)
|
||||||
|
Radio.set_enrichment_status!(ids, :hrrr_status, :complete)
|
||||||
|
end
|
||||||
|
|
||||||
|
{:ok, length(oconus) + length(to_complete)}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp contact_has_oconus_path_point?(contact) do
|
||||||
|
contact
|
||||||
|
|> Radio.contact_path_points()
|
||||||
|
|> Enum.any?(fn {lat, lon} ->
|
||||||
|
not Grid.contains?(%{"lat" => lat, "lon" => lon})
|
||||||
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue