Reduce cyclomatic complexity in clustering, encoding, and leader_election
Simplify complex functions to improve readability and maintainability: - clustering.ex: Convert case statement to map lookup for cluster radii - encoding.ex: Extract codepoint validation into separate function clauses - leader_election.ex: Extract PID liveness checking and cleanup logic into helpers Co-Authored-By: Graham <noreply@anthropic.com>
This commit is contained in:
parent
48be64583a
commit
d48a3a291f
3 changed files with 69 additions and 70 deletions
|
|
@ -186,53 +186,53 @@ defmodule Aprsme.Cluster.LeaderElection do
|
|||
defp cleanup_stale_registrations do
|
||||
case :global.whereis_name(@election_key) do
|
||||
:undefined ->
|
||||
# No registration exists
|
||||
:ok
|
||||
|
||||
pid when is_pid(pid) ->
|
||||
pid_node = node(pid)
|
||||
connected_nodes = [node() | Node.list()]
|
||||
|
||||
# Check if the PID's node is still connected
|
||||
if pid_node in connected_nodes do
|
||||
# Node is connected, try to check if process is alive
|
||||
try do
|
||||
if pid_node == node() do
|
||||
# Local PID - use Process.alive?
|
||||
if Process.alive?(pid) do
|
||||
:ok
|
||||
else
|
||||
Logger.info("Cleaning up stale leader registration for dead local process #{inspect(pid)}")
|
||||
:global.unregister_name(@election_key)
|
||||
end
|
||||
else
|
||||
# Remote PID - use RPC to check if alive
|
||||
case :rpc.call(pid_node, Process, :alive?, [pid]) do
|
||||
true ->
|
||||
:ok
|
||||
|
||||
false ->
|
||||
Logger.info("Cleaning up stale leader registration for dead remote process #{inspect(pid)}")
|
||||
:global.unregister_name(@election_key)
|
||||
|
||||
{:badrpc, _reason} ->
|
||||
Logger.info("Cleaning up stale leader registration for unreachable process #{inspect(pid)}")
|
||||
:global.unregister_name(@election_key)
|
||||
end
|
||||
end
|
||||
rescue
|
||||
_error ->
|
||||
Logger.info("Cleaning up stale leader registration for problematic process #{inspect(pid)}")
|
||||
:global.unregister_name(@election_key)
|
||||
end
|
||||
else
|
||||
# Node is disconnected - clean up the registration
|
||||
Logger.info("Cleaning up stale leader registration for disconnected node #{pid_node}")
|
||||
:global.unregister_name(@election_key)
|
||||
end
|
||||
check_and_cleanup_registration(pid)
|
||||
end
|
||||
end
|
||||
|
||||
defp check_and_cleanup_registration(pid) do
|
||||
pid_node = node(pid)
|
||||
connected_nodes = [node() | Node.list()]
|
||||
|
||||
if pid_node in connected_nodes do
|
||||
check_pid_liveness(pid, pid_node)
|
||||
else
|
||||
cleanup_registration("disconnected node #{pid_node}")
|
||||
end
|
||||
end
|
||||
|
||||
defp check_pid_liveness(pid, pid_node) do
|
||||
if is_pid_alive?(pid, pid_node) do
|
||||
:ok
|
||||
else
|
||||
reason = if pid_node == node(), do: "dead local process", else: "dead remote process"
|
||||
cleanup_registration("#{reason} #{inspect(pid)}")
|
||||
end
|
||||
rescue
|
||||
_error ->
|
||||
cleanup_registration("problematic process #{inspect(pid)}")
|
||||
end
|
||||
|
||||
defp is_pid_alive?(pid, pid_node) when pid_node == node() do
|
||||
Process.alive?(pid)
|
||||
end
|
||||
|
||||
defp is_pid_alive?(pid, pid_node) do
|
||||
if :rpc.call(pid_node, Process, :alive?, [pid]) do
|
||||
true
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
defp cleanup_registration(reason) do
|
||||
Logger.info("Cleaning up stale leader registration for #{reason}")
|
||||
:global.unregister_name(@election_key)
|
||||
end
|
||||
|
||||
defp get_cluster_wide_status do
|
||||
all_nodes = [node() | Node.list()]
|
||||
|
||||
|
|
|
|||
|
|
@ -155,25 +155,21 @@ defmodule Aprsme.Encoding do
|
|||
@spec valid_grapheme?(String.grapheme()) :: boolean()
|
||||
defp valid_grapheme?(grapheme) do
|
||||
case String.to_charlist(grapheme) do
|
||||
[cp] ->
|
||||
# Allow tab (0x09), newline (0x0A), carriage return (0x0D)
|
||||
# Remove other control characters
|
||||
case cp do
|
||||
9 -> true
|
||||
10 -> true
|
||||
13 -> true
|
||||
c when c >= 0 and c <= 31 -> false
|
||||
127 -> false
|
||||
c when c >= 128 and c <= 159 -> false
|
||||
_ -> true
|
||||
end
|
||||
|
||||
_ ->
|
||||
# Multi-codepoint grapheme, keep it
|
||||
true
|
||||
[cp] -> valid_codepoint?(cp)
|
||||
_ -> true
|
||||
end
|
||||
end
|
||||
|
||||
# Allow tab (0x09), newline (0x0A), carriage return (0x0D)
|
||||
# Remove other control characters
|
||||
defp valid_codepoint?(9), do: true
|
||||
defp valid_codepoint?(10), do: true
|
||||
defp valid_codepoint?(13), do: true
|
||||
defp valid_codepoint?(127), do: false
|
||||
defp valid_codepoint?(c) when c >= 0 and c <= 31, do: false
|
||||
defp valid_codepoint?(c) when c >= 128 and c <= 159, do: false
|
||||
defp valid_codepoint?(_), do: true
|
||||
|
||||
@spec find_invalid_byte_position(binary()) :: non_neg_integer() | nil
|
||||
defp find_invalid_byte_position(input) do
|
||||
input
|
||||
|
|
|
|||
|
|
@ -46,21 +46,24 @@ defmodule Aprsme.Packets.Clustering do
|
|||
Calculates the clustering radius in degrees based on zoom level.
|
||||
Lower zoom levels get larger radii for more aggressive clustering.
|
||||
"""
|
||||
# Clustering radius lookup table by zoom level
|
||||
# More aggressive scaling for better separation at higher zooms
|
||||
# Zoom 1: ~5 degrees, Zoom 5: ~0.3 degrees, Zoom 8: ~0.04 degrees
|
||||
@cluster_radii %{
|
||||
1 => 5.0,
|
||||
2 => 2.5,
|
||||
3 => 1.25,
|
||||
4 => 0.625,
|
||||
5 => 0.3125,
|
||||
6 => 0.15625,
|
||||
7 => 0.078125,
|
||||
8 => 0.0390625
|
||||
}
|
||||
@default_radius 0.0390625
|
||||
|
||||
@spec calculate_cluster_radius(integer()) :: float()
|
||||
def calculate_cluster_radius(zoom) do
|
||||
# More aggressive scaling for better separation at higher zooms
|
||||
# Zoom 1: ~5 degrees, Zoom 5: ~0.3 degrees, Zoom 8: ~0.04 degrees
|
||||
case zoom do
|
||||
1 -> 5.0
|
||||
2 -> 2.5
|
||||
3 -> 1.25
|
||||
4 -> 0.625
|
||||
5 -> 0.3125
|
||||
6 -> 0.15625
|
||||
7 -> 0.078125
|
||||
8 -> 0.0390625
|
||||
_ -> 0.0390625
|
||||
end
|
||||
Map.get(@cluster_radii, zoom, @default_radius)
|
||||
end
|
||||
|
||||
# Filter packets with valid lat/lon coordinates
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue