feat(rover-planning): backfill resets stale :complete paths to repopulate term blob
Existing Path rows persisted before the PathCompute extraction shipped have no "term" key in their result map, so the live /path page hits the :stale_term branch and falls back to live recompute when the operator clicks a row. The hourly backfill cron now flips those :complete rows back to :pending so the path-profile worker rerolls them with the new full-output term, after which row clicks render from cache instantly. The flip uses Postgres's jsonb_exists() so it's a single targeted UPDATE instead of pulling rows into Elixir.
This commit is contained in:
parent
c9aa9c53d5
commit
1abf452558
1 changed files with 24 additions and 7 deletions
|
|
@ -175,17 +175,20 @@ defmodule Microwaveprop.RoverPlanning do
|
|||
end
|
||||
|
||||
@doc """
|
||||
Walks every mission and re-enqueues any (rover_location × station)
|
||||
pair whose `Path` is missing or not `:complete`. Existing complete
|
||||
rows are left alone — the worker also short-circuits on `:complete`,
|
||||
so this is idempotent and safe to run on a cron.
|
||||
Walks every mission and re-enqueues any (rover_location × station ×
|
||||
band) pair whose `Path` is missing, not `:complete`, OR whose
|
||||
cached `result` lacks the `"term"` blob (paths persisted before
|
||||
PathCompute extraction shipped — the row click on /rover-planning
|
||||
needs that blob to render `/path` from cache instead of recomputing).
|
||||
|
||||
Use case: a rolling deploy or a transient elevation-API failure left
|
||||
some missions with `:pending` / `:failed` entries; the next backfill
|
||||
tick recovers them without operator action.
|
||||
Idempotent: the path-profile worker short-circuits on `:complete`,
|
||||
and we only nudge :complete rows back to :pending when their term
|
||||
is missing. Safe to run on a cron.
|
||||
"""
|
||||
@spec backfill_paths() :: :ok
|
||||
def backfill_paths do
|
||||
reset_paths_missing_term()
|
||||
|
||||
Mission
|
||||
|> Repo.all()
|
||||
|> Repo.preload(stations: from(s in Station, order_by: s.position))
|
||||
|
|
@ -194,6 +197,20 @@ defmodule Microwaveprop.RoverPlanning do
|
|||
:ok
|
||||
end
|
||||
|
||||
# Flip :complete paths whose result map has no "term" key back to
|
||||
# :pending so the next reconcile pass picks them up. JSONB
|
||||
# `key_exists` is `?` in pg, but Ecto's fragment uses `?` as a
|
||||
# placeholder — use the function form `jsonb_exists/2` instead.
|
||||
defp reset_paths_missing_term do
|
||||
Repo.update_all(
|
||||
from(p in Path,
|
||||
where: p.status == :complete,
|
||||
where: not fragment("jsonb_exists(?, 'term')", p.result)
|
||||
),
|
||||
set: [status: :pending]
|
||||
)
|
||||
end
|
||||
|
||||
defp enqueue_paths_for(%Mission{} = mission) do
|
||||
mission
|
||||
|> desired_tuples()
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue