fix: handle APRS status DB ownership exits

This commit is contained in:
Graham McIntire 2026-03-22 15:58:14 -05:00
parent 26e86ddba8
commit 8937c1fb57
No known key found for this signature in database
2 changed files with 50 additions and 4 deletions

View file

@ -129,6 +129,7 @@ defmodule Aprsme.Is do
# GenServer is not running (disconnected)
server = Application.get_env(:aprsme, :aprs_is_server, nil)
port = Application.get_env(:aprsme, :aprs_is_port, 14_580)
{stored_packet_count, oldest_packet_timestamp} = safe_packet_storage_stats()
%{
connected: false,
@ -139,8 +140,8 @@ defmodule Aprsme.Is do
login_id: Application.get_env(:aprsme, :aprs_is_login_id, "W5ISP"),
filter: Application.get_env(:aprsme, :aprs_is_default_filter, "r/33/-96/100"),
packet_stats: default_packet_stats(),
stored_packet_count: Aprsme.Packets.get_total_packet_count(),
oldest_packet_timestamp: Aprsme.Packets.get_oldest_packet_timestamp()
stored_packet_count: stored_packet_count,
oldest_packet_timestamp: oldest_packet_timestamp
}
_pid ->
@ -151,6 +152,7 @@ defmodule Aprsme.Is do
# GenServer exists but not responding
server = Application.get_env(:aprsme, :aprs_is_server, ~c"rotate.aprs2.net")
port = Application.get_env(:aprsme, :aprs_is_port, 14_580)
{stored_packet_count, oldest_packet_timestamp} = safe_packet_storage_stats()
%{
connected: false,
@ -161,13 +163,23 @@ defmodule Aprsme.Is do
login_id: Application.get_env(:aprsme, :aprs_is_login_id, "W5ISP"),
filter: Application.get_env(:aprsme, :aprs_is_default_filter, "r/33/-96/100"),
packet_stats: default_packet_stats(),
stored_packet_count: Aprsme.Packets.get_total_packet_count(),
oldest_packet_timestamp: Aprsme.Packets.get_oldest_packet_timestamp()
stored_packet_count: stored_packet_count,
oldest_packet_timestamp: oldest_packet_timestamp
}
end
end
end
defp safe_packet_storage_stats do
{Aprsme.Packets.get_total_packet_count(), Aprsme.Packets.get_oldest_packet_timestamp()}
rescue
DBConnection.OwnershipError ->
{0, nil}
catch
:exit, _ ->
{0, nil}
end
def set_filter(filter_string), do: send_message("#filter #{filter_string}")
def list_active_filters, do: send_message("#filter?")

View file

@ -7,6 +7,8 @@ defmodule Aprsme.IsTest do
import ExUnit.CaptureLog
alias Ecto.Adapters.SQL.Sandbox
# Helper to build a default GenServer state for direct callback testing
defp build_state(overrides \\ %{}) do
timer = Process.send_after(self(), :noop_timer, to_timeout(minute: 5))
@ -519,6 +521,38 @@ defmodule Aprsme.IsTest do
assert status.login_id == "TEST"
assert status.filter == "r/33/-96/100"
end
test "returns fallback packet storage stats when called from a non-owner process" do
parent = self()
owner =
spawn(fn ->
:ok = Sandbox.checkout(Aprsme.Repo)
send(parent, :sandbox_owner_ready)
receive do
:stop -> :ok
end
end)
assert_receive :sandbox_owner_ready
task =
Task.async(fn ->
receive do
:query_status -> Aprsme.Is.get_status()
end
end)
Sandbox.allow(Aprsme.Repo, owner, task.pid)
send(owner, :stop)
send(task.pid, :query_status)
status = Task.await(task)
assert status.connected == false
assert status.stored_packet_count == 0
assert status.oldest_packet_timestamp == nil
end
end
describe "buffer line extraction via TCP data" do