Two fixes: 1) Form save / rover-site add/remove no longer runs the path-matrix reconcile inline. update_mission and the show LiveView now enqueue a single RoverMissionReconcileWorker job and return — for missions with many rover sites x bands the inline path was firing hundreds of Multi inserts + Oban.inserts on the request. 2) RoverPathProfileWorker.load_path/1 now strictly matches a 4-tuple (mission_id, rover_location_id, station_id, band_mhz) with band_mhz as an integer, plus updates the Oban unique key set to include band_mhz so multi-band missions enqueue per-band jobs (not just one). Legacy/malformed args are logged and dropped instead of crashing the queue with MultipleResultsError.
45 lines
1.4 KiB
Elixir
45 lines
1.4 KiB
Elixir
defmodule Microwaveprop.Workers.RoverMissionReconcileWorker do
|
||
@moduledoc """
|
||
Async reconciler for one rover-planning mission's path matrix.
|
||
Form saves (mission edits, add/remove rover site) enqueue this job
|
||
instead of running the reconcile inline — for a mission with many
|
||
rover sites × stations × bands the inline path produced a multi-
|
||
hundred-row Multi transaction + as many `Oban.insert/1` calls,
|
||
which made the form submit feel sluggish.
|
||
|
||
The reconcile itself is idempotent: deleting stale (mission_id,
|
||
rover_location_id, station_id, band_mhz) rows, leaving :complete
|
||
rows in place, and enqueueing per-pair compute jobs only for the
|
||
tuples that aren't already represented.
|
||
"""
|
||
|
||
use Oban.Worker,
|
||
queue: :terrain,
|
||
priority: 3,
|
||
max_attempts: 3,
|
||
unique: [
|
||
period: 60,
|
||
keys: [:mission_id],
|
||
states: [:available, :scheduled, :executing, :retryable]
|
||
]
|
||
|
||
import Ecto.Query
|
||
|
||
alias Microwaveprop.Repo
|
||
alias Microwaveprop.RoverPlanning
|
||
alias Microwaveprop.RoverPlanning.Mission
|
||
alias Microwaveprop.RoverPlanning.Station
|
||
|
||
@impl Oban.Worker
|
||
def perform(%Oban.Job{args: %{"mission_id" => mission_id}}) do
|
||
case Repo.get(Mission, mission_id) do
|
||
nil ->
|
||
:ok
|
||
|
||
mission ->
|
||
mission
|
||
|> Repo.preload([:user, stations: from(s in Station, order_by: s.position)])
|
||
|> RoverPlanning.reconcile_mission_paths()
|
||
end
|
||
end
|
||
end
|