Fix Credo issues and telemetry Decimal coercion
- Extract prepare_markers_for_push/2 to reduce nesting depth in handle_info - Split detect_item_or_object into smaller predicate and application functions to reduce cyclomatic complexity - Coerce Decimal/nil values to native numbers in telemetry metrics (PostgreSQL sum() returns numeric type mapped to Decimal by Postgrex) - Align locate button horizontally with zoom controls
This commit is contained in:
parent
8dbf8d3c20
commit
d09e015857
3 changed files with 72 additions and 55 deletions
|
|
@ -479,36 +479,44 @@ defmodule Aprsme.PacketConsumer do
|
||||||
# Detect if packet is an item or object and set appropriate fields
|
# Detect if packet is an item or object and set appropriate fields
|
||||||
defp detect_item_or_object(attrs) do
|
defp detect_item_or_object(attrs) do
|
||||||
cond do
|
cond do
|
||||||
# Check for object data type or information field starting with ;
|
object_packet?(attrs) -> apply_object_fields(attrs)
|
||||||
attrs[:data_type] == "object" or attrs["data_type"] == "object" or
|
item_packet?(attrs) -> apply_item_fields(attrs)
|
||||||
(is_binary(attrs[:information_field]) and
|
true -> attrs
|
||||||
String.starts_with?(attrs[:information_field], ";")) ->
|
|
||||||
# Try data_extended first, then fall back to parsing information_field
|
|
||||||
object_name =
|
|
||||||
extract_object_name(attrs) ||
|
|
||||||
extract_object_name_from_info_field(attrs[:information_field])
|
|
||||||
|
|
||||||
attrs
|
|
||||||
|> Map.put(:object_name, object_name)
|
|
||||||
|> Map.put(:is_object, true)
|
|
||||||
|> Map.delete(:itemname)
|
|
||||||
|> Map.delete("itemname")
|
|
||||||
|
|
||||||
# Check for itemname field from parser
|
|
||||||
Map.has_key?(attrs, :itemname) or Map.has_key?(attrs, "itemname") ->
|
|
||||||
item_name = Map.get(attrs, :itemname) || Map.get(attrs, "itemname")
|
|
||||||
|
|
||||||
attrs
|
|
||||||
|> Map.put(:item_name, item_name)
|
|
||||||
|> Map.put(:is_item, true)
|
|
||||||
|> Map.delete(:itemname)
|
|
||||||
|> Map.delete("itemname")
|
|
||||||
|
|
||||||
true ->
|
|
||||||
attrs
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp object_packet?(attrs) do
|
||||||
|
attrs[:data_type] == "object" or attrs["data_type"] == "object" or
|
||||||
|
(is_binary(attrs[:information_field]) and
|
||||||
|
String.starts_with?(attrs[:information_field], ";"))
|
||||||
|
end
|
||||||
|
|
||||||
|
defp item_packet?(attrs) do
|
||||||
|
Map.has_key?(attrs, :itemname) or Map.has_key?(attrs, "itemname")
|
||||||
|
end
|
||||||
|
|
||||||
|
defp apply_object_fields(attrs) do
|
||||||
|
object_name =
|
||||||
|
extract_object_name(attrs) ||
|
||||||
|
extract_object_name_from_info_field(attrs[:information_field])
|
||||||
|
|
||||||
|
attrs
|
||||||
|
|> Map.put(:object_name, object_name)
|
||||||
|
|> Map.put(:is_object, true)
|
||||||
|
|> Map.delete(:itemname)
|
||||||
|
|> Map.delete("itemname")
|
||||||
|
end
|
||||||
|
|
||||||
|
defp apply_item_fields(attrs) do
|
||||||
|
item_name = Map.get(attrs, :itemname) || Map.get(attrs, "itemname")
|
||||||
|
|
||||||
|
attrs
|
||||||
|
|> Map.put(:item_name, item_name)
|
||||||
|
|> Map.put(:is_item, true)
|
||||||
|
|> Map.delete(:itemname)
|
||||||
|
|> Map.delete("itemname")
|
||||||
|
end
|
||||||
|
|
||||||
defp extract_object_name(attrs) do
|
defp extract_object_name(attrs) do
|
||||||
case attrs[:data_extended] do
|
case attrs[:data_extended] do
|
||||||
%{name: name} when is_binary(name) -> name
|
%{name: name} when is_binary(name) -> name
|
||||||
|
|
|
||||||
|
|
@ -130,7 +130,7 @@ defmodule Aprsme.Telemetry.DatabaseMetrics do
|
||||||
defp collect_database_size do
|
defp collect_database_size do
|
||||||
case Aprsme.Repo.query("SELECT pg_database_size(current_database()) as size") do
|
case Aprsme.Repo.query("SELECT pg_database_size(current_database()) as size") do
|
||||||
{:ok, %{rows: [[size]]}} ->
|
{:ok, %{rows: [[size]]}} ->
|
||||||
:telemetry.execute([:aprsme, :postgres, :database], %{size_bytes: size}, %{})
|
:telemetry.execute([:aprsme, :postgres, :database], %{size_bytes: to_number(size)}, %{})
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
:ok
|
:ok
|
||||||
|
|
@ -152,11 +152,11 @@ defmodule Aprsme.Telemetry.DatabaseMetrics do
|
||||||
:telemetry.execute(
|
:telemetry.execute(
|
||||||
[:aprsme, :postgres, :connections],
|
[:aprsme, :postgres, :connections],
|
||||||
%{
|
%{
|
||||||
total: total || 0,
|
total: to_number(total),
|
||||||
active: active || 0,
|
active: to_number(active),
|
||||||
idle: idle || 0,
|
idle: to_number(idle),
|
||||||
idle_in_transaction: idle_in_tx || 0,
|
idle_in_transaction: to_number(idle_in_tx),
|
||||||
waiting: waiting || 0
|
waiting: to_number(waiting)
|
||||||
},
|
},
|
||||||
%{}
|
%{}
|
||||||
)
|
)
|
||||||
|
|
@ -202,10 +202,10 @@ defmodule Aprsme.Telemetry.DatabaseMetrics do
|
||||||
:telemetry.execute(
|
:telemetry.execute(
|
||||||
[:aprsme, :postgres, :query_stats],
|
[:aprsme, :postgres, :query_stats],
|
||||||
%{
|
%{
|
||||||
total_calls: trunc(calls || 0),
|
total_calls: to_number(calls, :integer),
|
||||||
total_time_ms: total_time || 0,
|
total_time_ms: to_number(total_time),
|
||||||
avg_time_ms: avg_time || 0,
|
avg_time_ms: to_number(avg_time),
|
||||||
max_time_ms: max_time || 0
|
max_time_ms: to_number(max_time)
|
||||||
},
|
},
|
||||||
%{}
|
%{}
|
||||||
)
|
)
|
||||||
|
|
@ -239,15 +239,26 @@ defmodule Aprsme.Telemetry.DatabaseMetrics do
|
||||||
:telemetry.execute(
|
:telemetry.execute(
|
||||||
[:aprsme, :postgres, :packets_table],
|
[:aprsme, :postgres, :packets_table],
|
||||||
%{
|
%{
|
||||||
live_tuples: live || 0,
|
live_tuples: to_number(live),
|
||||||
dead_tuples: dead || 0,
|
dead_tuples: to_number(dead),
|
||||||
total_inserts: ins || 0,
|
total_inserts: to_number(ins),
|
||||||
total_updates: upd || 0,
|
total_updates: to_number(upd),
|
||||||
total_deletes: del || 0,
|
total_deletes: to_number(del),
|
||||||
table_size_bytes: table_size || 0,
|
table_size_bytes: to_number(table_size),
|
||||||
indexes_size_bytes: idx_size || 0
|
indexes_size_bytes: to_number(idx_size)
|
||||||
},
|
},
|
||||||
%{}
|
%{}
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Coerce Decimal/nil values to native Erlang numbers for :telemetry.execute
|
||||||
|
defp to_number(nil), do: 0
|
||||||
|
defp to_number(%Decimal{} = d), do: Decimal.to_float(d)
|
||||||
|
defp to_number(n) when is_number(n), do: n
|
||||||
|
defp to_number(_), do: 0
|
||||||
|
|
||||||
|
defp to_number(nil, :integer), do: 0
|
||||||
|
defp to_number(%Decimal{} = d, :integer), do: d |> Decimal.to_float() |> trunc()
|
||||||
|
defp to_number(n, :integer) when is_number(n), do: trunc(n)
|
||||||
|
defp to_number(_, :integer), do: 0
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -885,16 +885,7 @@ defmodule AprsmeWeb.MapLive.Index do
|
||||||
|> Enum.filter(& &1)
|
|> Enum.filter(& &1)
|
||||||
|> Enum.uniq()
|
|> Enum.uniq()
|
||||||
|
|
||||||
markers =
|
markers = prepare_markers_for_push(reversed, socket.assigns.station_popup_open)
|
||||||
Enum.map(reversed, fn data ->
|
|
||||||
data = Map.delete(data, "convert_from")
|
|
||||||
|
|
||||||
if socket.assigns.station_popup_open do
|
|
||||||
Map.put(data, :openPopup, false)
|
|
||||||
else
|
|
||||||
data
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
push_event(socket, "new_packets", %{
|
push_event(socket, "new_packets", %{
|
||||||
packets: markers,
|
packets: markers,
|
||||||
|
|
@ -1013,6 +1004,13 @@ defmodule AprsmeWeb.MapLive.Index do
|
||||||
|
|
||||||
# Private handler functions for each message type
|
# Private handler functions for each message type
|
||||||
|
|
||||||
|
defp prepare_markers_for_push(markers, popup_open?) do
|
||||||
|
Enum.map(markers, fn data ->
|
||||||
|
data = Map.delete(data, "convert_from")
|
||||||
|
if popup_open?, do: Map.put(data, :openPopup, false), else: data
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
defp handle_info_process_bounds_update(map_bounds, socket) do
|
defp handle_info_process_bounds_update(map_bounds, socket) do
|
||||||
require Logger
|
require Logger
|
||||||
|
|
||||||
|
|
@ -1151,7 +1149,7 @@ defmodule AprsmeWeb.MapLive.Index do
|
||||||
<style>
|
<style>
|
||||||
.locate-button {
|
.locate-button {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 10px;
|
left: 12px;
|
||||||
top: 100px;
|
top: 100px;
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
background: white;
|
background: white;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue