aprs.me/lib/aprsme/cluster/packet_receiver.ex
Graham McIntire 4804bd16be
Add distributed Erlang clustering for single APRS-IS connection
Implement leader election to ensure only one APRS-IS connection across
multiple Kubernetes replicas. This prevents duplicate packet processing
and respects APRS-IS usage policies.

Key changes:
- Add leader election using :global registry
- Create connection manager for dynamic APRS-IS management
- Implement packet distribution from leader to all nodes
- Add Kubernetes headless service for node discovery
- Configure DNS-based clustering with libcluster
- Update deployment to support 3 replicas with clustering

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-25 10:30:29 -05:00

41 lines
1,009 B
Elixir

defmodule Aprsme.Cluster.PacketReceiver do
@moduledoc """
Receives distributed packets from the cluster leader on non-leader nodes.
Ensures all nodes can serve real-time updates even though only the leader
processes APRS packets.
"""
use GenServer
alias Aprsme.Cluster.PacketDistributor
require Logger
def start_link(opts) do
GenServer.start_link(__MODULE__, opts, name: __MODULE__)
end
@impl true
def init(_opts) do
# Subscribe to distributed packets
PacketDistributor.subscribe()
Logger.info("Started packet receiver on node #{node()}")
{:ok, %{}}
end
@impl true
def handle_info({:distributed_packet, packet}, state) do
# Only process if we're not the leader (leader already processed locally)
if !Aprsme.Cluster.LeaderElection.is_leader?() do
PacketDistributor.handle_distributed_packet({:distributed_packet, packet})
end
{:noreply, state}
end
@impl true
def handle_info(_msg, state) do
{:noreply, state}
end
end