From 82b515e88d62b083b194155f65467cd3ae1f6e8c Mon Sep 17 00:00:00 2001 From: Graham McIntire Date: Sun, 26 Apr 2026 12:05:32 -0500 Subject: [PATCH] feat(rover): include step number/total in Calculate progress label --- lib/microwaveprop/rover/compute.ex | 29 +++++++++++++++-------- lib/microwaveprop_web/live/rover_live.ex | 6 ++--- test/microwaveprop/rover/compute_test.exs | 11 +++++---- 3 files changed, 28 insertions(+), 18 deletions(-) diff --git a/lib/microwaveprop/rover/compute.ex b/lib/microwaveprop/rover/compute.ex index 74fcb98e..66cc9058 100644 --- a/lib/microwaveprop/rover/compute.ex +++ b/lib/microwaveprop/rover/compute.ex @@ -90,7 +90,7 @@ defmodule Microwaveprop.Rover.Compute do Keyword.get(deps, :buildings_clutter_lookup, &default_building_clutter/1) hilltop_snap = Keyword.get(deps, :hilltop_snap, &Hilltop.snap/1) - progress = Keyword.get(deps, :progress, fn _ -> :ok end) + progress = Keyword.get(deps, :progress, fn _, _, _ -> :ok end) %{ home: home, @@ -106,7 +106,16 @@ defmodule Microwaveprop.Rover.Compute do radius_km = max_distance_km * 1.0 bbox = bbox_around(home, radius_km) - progress.("Loading propagation grid") + road_enabled? = Application.get_env(:microwaveprop, :rover_road_proximity_enabled, true) + total_steps = if road_enabled?, do: 8, else: 7 + counter = :counters.new(1, [:atomics]) + + step = fn label -> + :counters.add(counter, 1, 1) + progress.(label, :counters.get(counter, 1), total_steps) + end + + step.("Loading propagation grid") raw_cells = time_step("scores_at", fn -> scores_at.(band_mhz, valid_time, bbox) end) in_radius = @@ -119,26 +128,26 @@ defmodule Microwaveprop.Rover.Compute do ) points = Enum.map(in_radius, &{&1.lat, &1.lon}) - progress.("Looking up elevation") + step.("Looking up elevation") elev_map = time_step("elev_lookup", fn -> elev_lookup.(points) end) - progress.("Loading building footprints") + step.("Loading building footprints") _ = time_step("buildings_load", fn -> BuildingsLoader.ensure_loaded_for_bbox(bbox) end) - progress.("Computing path clearance") + step.("Computing path clearance") clearance_map = time_step("clearance", fn -> clearance_lookup.(in_radius, selected_stations) end) - progress.("Measuring terrain prominence") + step.("Measuring terrain prominence") prominence_map = time_step("prominence", fn -> prominence_lookup.(in_radius) end) road_map = - if Application.get_env(:microwaveprop, :rover_road_proximity_enabled, true) do - progress.("Checking road access") + if road_enabled? do + step.("Checking road access") time_step("road_proximity", fn -> fetch_road_map(road_lookup, in_radius, bbox) end) else %{} end - progress.("Scanning building clutter") + step.("Scanning building clutter") clutter_map = time_step("building_clutter", fn -> buildings_clutter_lookup.(in_radius) end) - progress.("Scoring cells") + step.("Scoring cells") home_elev = home.elev_m || 0 diff --git a/lib/microwaveprop_web/live/rover_live.ex b/lib/microwaveprop_web/live/rover_live.ex index a9b14005..563f4c00 100644 --- a/lib/microwaveprop_web/live/rover_live.ex +++ b/lib/microwaveprop_web/live/rover_live.ex @@ -349,8 +349,8 @@ defmodule MicrowavepropWeb.RoverLive do end @impl true - def handle_info({:rover_progress, label}, socket) do - {:noreply, assign(socket, scoring_step: label)} + def handle_info({:rover_progress, label, n, total}, socket) do + {:noreply, assign(socket, scoring_step: "#{n}/#{total} · #{label}")} end defp apply_scoring_warnings(socket, []), do: clear_flash(socket) @@ -705,7 +705,7 @@ defmodule MicrowavepropWeb.RoverLive do defp start_scoring(socket) do args = scoring_args(socket) pid = self() - progress = fn label -> send(pid, {:rover_progress, label}) end + progress = fn label, n, total -> send(pid, {:rover_progress, label, n, total}) end socket |> assign(scoring_loading: true, scoring_step: "Starting…") diff --git a/test/microwaveprop/rover/compute_test.exs b/test/microwaveprop/rover/compute_test.exs index d060948f..52123245 100644 --- a/test/microwaveprop/rover/compute_test.exs +++ b/test/microwaveprop/rover/compute_test.exs @@ -135,7 +135,7 @@ defmodule Microwaveprop.Rover.ComputeTest do grid = build_grid(home.lat, home.lon) test_pid = self() - progress = fn label -> send(test_pid, {:progress, label}) end + progress = fn label, step, total -> send(test_pid, {:progress, label, step, total}) end Compute.run( %{ @@ -155,10 +155,11 @@ defmodule Microwaveprop.Rover.ComputeTest do progress: progress ) - assert_received {:progress, "Loading propagation grid"} - assert_received {:progress, "Looking up elevation"} - assert_received {:progress, "Computing path clearance"} - assert_received {:progress, "Scoring cells"} + assert_received {:progress, "Loading propagation grid", 1, total} + assert is_integer(total) and total >= 7 + assert_received {:progress, "Looking up elevation", 2, ^total} + assert_received {:progress, "Computing path clearance", _, ^total} + assert_received {:progress, "Scoring cells", ^total, ^total} end test "filters cells failing min_elev_gain" do