fix(weather): drop valid_times older than one hour from the timeline
The HRRR scalar cache can hold a previous run's forecast hours past their useful life — the timeline was offering "current conditions" points that were 2-3 hours old, which is more misleading than helpful on a map labeled "Now". Filter Weather.available_weather_valid_times() through a `now - 1h` cutoff in mount, :weather_updated, and :propagation_pipeline_progress so the timeline only ever shows the most recent analysis hour plus forecast hours.
This commit is contained in:
parent
b66024e0c3
commit
9e4ca154ff
2 changed files with 36 additions and 3 deletions
|
|
@ -27,7 +27,7 @@ defmodule MicrowavepropWeb.WeatherMapLive do
|
|||
# the LiveView socket join timeout. The client now paints weather
|
||||
# through a tile endpoint, so mount only needs the selected layer
|
||||
# and valid_time metadata.
|
||||
valid_times = Weather.available_weather_valid_times()
|
||||
valid_times = recent_valid_times(Weather.available_weather_valid_times())
|
||||
initial_vt = pick_initial_valid_time(valid_times)
|
||||
|
||||
{:ok,
|
||||
|
|
@ -65,6 +65,15 @@ defmodule MicrowavepropWeb.WeatherMapLive do
|
|||
Enum.min_by(valid_times, fn vt -> abs(DateTime.diff(vt, now, :second)) end)
|
||||
end
|
||||
|
||||
# Drop valid_times older than one hour ago. The HRRR scalar cache can
|
||||
# hold the previous run's forecast hours past their useful life;
|
||||
# showing 3-hour-old "current conditions" on the map is more
|
||||
# misleading than helpful.
|
||||
defp recent_valid_times(valid_times) do
|
||||
cutoff = DateTime.add(DateTime.utc_now(), -3600, :second)
|
||||
Enum.filter(valid_times, fn vt -> DateTime.compare(vt, cutoff) != :lt end)
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_event("select_layer", %{"layer" => layer_id}, socket) do
|
||||
if MapLayers.valid_id?(layer_id) do
|
||||
|
|
@ -122,7 +131,7 @@ defmodule MicrowavepropWeb.WeatherMapLive do
|
|||
|
||||
@impl true
|
||||
def handle_info({:weather_updated, _valid_time}, socket) do
|
||||
valid_times = Weather.available_weather_valid_times()
|
||||
valid_times = recent_valid_times(Weather.available_weather_valid_times())
|
||||
|
||||
# Keep whatever the user has scrubbed to if it's still available,
|
||||
# otherwise fall back to the latest on-disk time (GridCache-backed
|
||||
|
|
@ -152,7 +161,7 @@ defmodule MicrowavepropWeb.WeatherMapLive do
|
|||
# so the timeline picks up the extra hour, but keep the currently
|
||||
# selected time where it is.
|
||||
def handle_info({:propagation_pipeline_progress, _progress}, socket) do
|
||||
valid_times = Weather.available_weather_valid_times()
|
||||
valid_times = recent_valid_times(Weather.available_weather_valid_times())
|
||||
|
||||
if valid_times == socket.assigns.valid_times do
|
||||
{:noreply, socket}
|
||||
|
|
|
|||
|
|
@ -75,6 +75,30 @@ defmodule MicrowavepropWeb.WeatherMapLiveTest do
|
|||
end)
|
||||
end
|
||||
|
||||
test "mount drops valid_times older than one hour ago", %{conn: conn} do
|
||||
now =
|
||||
DateTime.utc_now()
|
||||
|> DateTime.truncate(:second)
|
||||
|> Map.put(:minute, 0)
|
||||
|> Map.put(:second, 0)
|
||||
|
||||
stale_t = DateTime.add(now, -2 * 3600, :second)
|
||||
recent_t = DateTime.add(now, -30 * 60, :second)
|
||||
future_t = DateTime.add(now, 3 * 3600, :second)
|
||||
|
||||
Enum.each([stale_t, recent_t, future_t], &write_profile(&1, 33.0, -97.0))
|
||||
|
||||
{:ok, _lv, html} = live(conn, ~p"/weather")
|
||||
|
||||
stale_iso = DateTime.to_iso8601(stale_t)
|
||||
recent_iso = DateTime.to_iso8601(recent_t)
|
||||
future_iso = DateTime.to_iso8601(future_t)
|
||||
|
||||
refute html =~ stale_iso, "stale valid_time #{stale_iso} should be filtered out"
|
||||
assert html =~ recent_iso, "recent valid_time #{recent_iso} should be present"
|
||||
assert html =~ future_iso, "future valid_time #{future_iso} should be present"
|
||||
end
|
||||
|
||||
test "mount defaults to the valid_time closest to now, not the latest forecast hour",
|
||||
%{conn: conn} do
|
||||
base =
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue