Current section
Files
Jump to
Current section
Files
src/strategy/elector_strategy_behaviour.erl
%%%-----------------------------------------------------------------------------
%% @doc Defines the base behaviour for election strategies.
%% @end
%%%-----------------------------------------------------------------------------
-module(elector_strategy_behaviour).
%%------------------------------------------------------------------------------
%% Callbacks
%%------------------------------------------------------------------------------
-callback elect(CandidateNodes :: candidate_nodes()) -> Leader :: leader().
%%------------------------------------------------------------------------------
%% Exported API
%%------------------------------------------------------------------------------
-export([elect/0, candidate_nodes/0]).
%%------------------------------------------------------------------------------
%% Type definitions
%%------------------------------------------------------------------------------
-type leader() :: node().
-type candidate_nodes() :: [node()].
%%------------------------------------------------------------------------------
%% Exported functions
%%------------------------------------------------------------------------------
%% @doc Starts the election process by triggering the strategy
%% modules elect() function.
%% The election implementation should only contain the logic for
%% selecting the leader node and returning the leader node name.
%% The elect/0 function is triggered on all nodes automatically
%% by the elector application. This means the strategy implementation
%% does not have to worry about starting the election on all nodes.
%% @end
-spec elect() -> Leader :: leader().
elect() ->
CandidateNodes = candidate_nodes(),
erlang:apply(
elector_config_handler:strategy_module(), elect, [CandidateNodes]).
%% @doc Returns a list of nodes that are eligible to become the leader.
%% @end
-spec candidate_nodes() -> CandidateNodes :: candidate_nodes().
candidate_nodes() ->
NodeCandidationFun =
fun() ->
Pid = erlang:whereis(elector_candidate),
case Pid of
undefined ->
{ok, false};
_ ->
gen_server:call(Pid, is_candidate_node)
end
end,
Responses = elector_service:async_call(NodeCandidationFun, [node() | nodes()]),
[Node || {Node, {response, {ok, IsCandidate}}} <- Responses, IsCandidate =:= true].