refactor: pattern-match LeaderElection init and cluster-status dispatch

- get_cluster_aprs_status: fetch_cluster_status/1 dispatches on the
  clustering flag — true fans out cluster-wide, false goes straight to
  the local Aprsme.Is status.
- init/1: extract schedule_initial_election/1 with true/false heads.
  The clustered branch sets up the check-and-backstop timers; the
  non-clustered branch queues an immediate election. Makes the two
  startup paths obvious from the function signatures.

No behavior change; all 17 LeaderElection tests still pass.
This commit is contained in:
Graham McIntire 2026-04-23 14:56:02 -05:00
parent f943d887c5
commit 401d43be62
No known key found for this signature in database
GPG key ID: F4ABF488E6029E59

View file

@ -50,33 +50,17 @@ defmodule Aprsme.Cluster.LeaderElection do
Returns the status from whichever node has an active connection.
"""
def get_cluster_aprs_status do
cluster_enabled = Application.get_env(:aprsme, :cluster_enabled, false)
if cluster_enabled do
get_cluster_wide_status()
else
# Non-clustered mode - just return local status
Aprsme.Is.get_status()
end
fetch_cluster_status(Application.get_env(:aprsme, :cluster_enabled, false))
end
defp fetch_cluster_status(true), do: get_cluster_wide_status()
defp fetch_cluster_status(false), do: Aprsme.Is.get_status()
@impl true
def init(_opts) do
Logger.info("Starting leader election process")
cluster_enabled = Application.get_env(:aprsme, :cluster_enabled, false)
if cluster_enabled do
Logger.info("Clustering enabled - waiting for cluster formation before leader election")
# Wait for cluster to form, then check periodically
Process.send_after(self(), :check_cluster_and_elect, 2_000)
# Set a timeout to force election if cluster doesn't form
Process.send_after(self(), :force_election_timeout, @max_cluster_wait)
else
Logger.info("Clustering disabled - proceeding with immediate leader election")
# Non-clustered mode - elect immediately
Process.send_after(self(), :attempt_election, 100)
end
schedule_initial_election(cluster_enabled)
# Schedule periodic checks
Process.send_after(self(), :check_leadership, @check_interval)
@ -87,6 +71,19 @@ defmodule Aprsme.Cluster.LeaderElection do
{:ok, %__MODULE__{cluster_enabled: cluster_enabled}}
end
# Clustered mode: wait for formation, then elect; schedule a backstop timeout.
defp schedule_initial_election(true) do
Logger.info("Clustering enabled - waiting for cluster formation before leader election")
Process.send_after(self(), :check_cluster_and_elect, 2_000)
Process.send_after(self(), :force_election_timeout, @max_cluster_wait)
end
# Non-clustered mode: elect immediately.
defp schedule_initial_election(false) do
Logger.info("Clustering disabled - proceeding with immediate leader election")
Process.send_after(self(), :attempt_election, 100)
end
@impl true
def handle_info(:check_cluster_and_elect, state) do
# Don't keep checking if election was already forced