perf: debounce BadPacketsLive refresh, remove stale test cases
Coalesce rapid PubSub notifications into single 2-second delayed DB query. Remove tests for removed :update_time_display handler. Ultraworked with Sisyphus Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
parent
3169abf0f0
commit
73c6703102
3 changed files with 29 additions and 21 deletions
|
|
@ -7,24 +7,24 @@ defmodule AprsmeWeb.BadPacketsLive.Index do
|
||||||
alias Aprsme.BadPacket
|
alias Aprsme.BadPacket
|
||||||
alias Aprsme.Repo
|
alias Aprsme.Repo
|
||||||
|
|
||||||
|
@debounce_ms 2_000
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def mount(_params, _session, socket) do
|
def mount(_params, _session, socket) do
|
||||||
if connected?(socket) do
|
if connected?(socket) do
|
||||||
# Subscribe to Postgres notifications for bad packets
|
|
||||||
:ok = Phoenix.PubSub.subscribe(Aprsme.PubSub, "postgres:aprsme_events")
|
:ok = Phoenix.PubSub.subscribe(Aprsme.PubSub, "postgres:aprsme_events")
|
||||||
# Load initial bad packets
|
|
||||||
bad_packets = fetch_bad_packets()
|
bad_packets = fetch_bad_packets()
|
||||||
# Extra safeguard to ensure we never show more than 100
|
|
||||||
limited_packets = Enum.take(bad_packets, 100)
|
limited_packets = Enum.take(bad_packets, 100)
|
||||||
|
|
||||||
{:ok,
|
{:ok,
|
||||||
assign(socket,
|
assign(socket,
|
||||||
bad_packets: limited_packets,
|
bad_packets: limited_packets,
|
||||||
loading: false,
|
loading: false,
|
||||||
last_updated: DateTime.utc_now()
|
last_updated: DateTime.utc_now(),
|
||||||
|
refresh_timer: nil
|
||||||
)}
|
)}
|
||||||
else
|
else
|
||||||
{:ok, assign(socket, bad_packets: [], loading: false, last_updated: nil)}
|
{:ok, assign(socket, bad_packets: [], loading: false, last_updated: nil, refresh_timer: nil)}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -39,33 +39,48 @@ defmodule AprsmeWeb.BadPacketsLive.Index do
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def handle_event("refresh", _params, socket) do
|
def handle_event("refresh", _params, socket) do
|
||||||
send(self(), :do_refresh)
|
_ = cancel_timer(socket.assigns.refresh_timer)
|
||||||
{:noreply, assign(socket, loading: true)}
|
socket = assign(socket, loading: true)
|
||||||
|
{:noreply, do_debounced_refresh(socket)}
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def handle_info({:postgres_notify, _payload}, socket) do
|
def handle_info({:postgres_notify, _payload}, socket) do
|
||||||
# Optionally filter payload for bad packet events
|
{:noreply, debounce_refresh(socket)}
|
||||||
send(self(), :do_refresh)
|
|
||||||
{:noreply, socket}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def handle_info(:do_refresh, socket) do
|
def handle_info(:do_refresh, socket) do
|
||||||
bad_packets = fetch_bad_packets()
|
bad_packets = fetch_bad_packets()
|
||||||
# Extra safeguard to ensure we never show more than 100
|
|
||||||
limited_packets = Enum.take(bad_packets, 100)
|
limited_packets = Enum.take(bad_packets, 100)
|
||||||
|
|
||||||
{:noreply,
|
{:noreply,
|
||||||
assign(socket,
|
assign(socket,
|
||||||
bad_packets: limited_packets,
|
bad_packets: limited_packets,
|
||||||
loading: false,
|
loading: false,
|
||||||
last_updated: DateTime.utc_now()
|
last_updated: DateTime.utc_now(),
|
||||||
|
refresh_timer: nil
|
||||||
)}
|
)}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp debounce_refresh(socket) do
|
||||||
|
_ = cancel_timer(socket.assigns.refresh_timer)
|
||||||
|
timer_ref = Process.send_after(self(), :do_refresh, @debounce_ms)
|
||||||
|
assign(socket, refresh_timer: timer_ref)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp do_debounced_refresh(socket) do
|
||||||
|
timer_ref = Process.send_after(self(), :do_refresh, @debounce_ms)
|
||||||
|
assign(socket, refresh_timer: timer_ref)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp cancel_timer(nil), do: :ok
|
||||||
|
|
||||||
|
defp cancel_timer(ref) do
|
||||||
|
Process.cancel_timer(ref)
|
||||||
|
end
|
||||||
|
|
||||||
defp fetch_bad_packets(limit \\ 100) do
|
defp fetch_bad_packets(limit \\ 100) do
|
||||||
# Hard cap at 100 to prevent showing too many records
|
|
||||||
actual_limit = min(limit, 100)
|
actual_limit = min(limit, 100)
|
||||||
|
|
||||||
BadPacket
|
BadPacket
|
||||||
|
|
|
||||||
|
|
@ -291,12 +291,6 @@ defmodule AprsmeWeb.MapLive.IndexTest do
|
||||||
assert render(view) =~ "aprs-map"
|
assert render(view) =~ "aprs-map"
|
||||||
end
|
end
|
||||||
|
|
||||||
test "responds to :update_time_display", %{conn: conn} do
|
|
||||||
{:ok, view, _html} = live(conn, "/", on_error: :warn)
|
|
||||||
send(view.pid, :update_time_display)
|
|
||||||
assert render(view) =~ "aprs-map"
|
|
||||||
end
|
|
||||||
|
|
||||||
test "responds to :cleanup_old_packets", %{conn: conn} do
|
test "responds to :cleanup_old_packets", %{conn: conn} do
|
||||||
{:ok, view, _html} = live(conn, "/", on_error: :warn)
|
{:ok, view, _html} = live(conn, "/", on_error: :warn)
|
||||||
send(view.pid, :cleanup_old_packets)
|
send(view.pid, :cleanup_old_packets)
|
||||||
|
|
|
||||||
|
|
@ -298,12 +298,11 @@ defmodule AprsmeWeb.MapLive.IntegrationTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "MapLive handle_info coverage" do
|
describe "MapLive handle_info coverage" do
|
||||||
test ":cleanup_old_packets, :update_time_display, :reload_historical_packets do not crash", %{conn: conn} do
|
test ":cleanup_old_packets, :reload_historical_packets do not crash", %{conn: conn} do
|
||||||
{:ok, view, _html} = live(conn, "/?lat=33.0&lng=-96.0&z=10", on_error: :warn)
|
{:ok, view, _html} = live(conn, "/?lat=33.0&lng=-96.0&z=10", on_error: :warn)
|
||||||
render_hook(view, "map_ready", %{})
|
render_hook(view, "map_ready", %{})
|
||||||
|
|
||||||
send(view.pid, :cleanup_old_packets)
|
send(view.pid, :cleanup_old_packets)
|
||||||
send(view.pid, :update_time_display)
|
|
||||||
send(view.pid, :reload_historical_packets)
|
send(view.pid, :reload_historical_packets)
|
||||||
Process.sleep(50)
|
Process.sleep(50)
|
||||||
assert render(view) =~ "aprs-map"
|
assert render(view) =~ "aprs-map"
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue