Current section

Files

Jump to
ra include ra.hrl
Raw

include/ra.hrl

-type maybe(T) :: undefined | T.
%%
%% Most of the records here are covered on Figure 2
%% in the Raft paper (extended version):
%% https://raft.github.io/raft.pdf.
%%
%% taken from gen_statem as this type isn't exported for some reason.
-type from() ::
{To :: pid(), Tag :: term()}.
%% Sections 5.1 in the paper.
-type ra_index() :: non_neg_integer().
%% Section 5.3.
-type ra_term() :: non_neg_integer().
%% tuple form of index and term
-type ra_idxterm() :: {ra_index(), ra_term()}.
%% Sections 5.1-5.3.
%% a friendly name for the cluster
-type ra_cluster_name() :: binary() | string() | atom().
%% Uniquely identifies a ra server on a local erlang node
%% used for on disk resources and local name to pid mapping
-type ra_uid() :: binary().
%% Identifies a ra server in a ra cluster
%% NB: ra servers need to be registered as need to be reachable under the old
%% name after restarts. Pids won't do.
-type ra_server_id() :: atom() | {Name :: atom(), Node :: node()}.
-type ra_peer_state() :: #{next_index => non_neg_integer(),
match_index => non_neg_integer(),
% the commit index last sent
% used for evaluating pipeline status
commit_index_sent => non_neg_integer()}.
-type ra_cluster() :: #{ra_server_id() => ra_peer_state()}.
-type ra_cluster_servers() :: [ra_server_id()].
%% represent a unique entry in the ra log
-type log_entry() :: {ra_index(), ra_term(), term()}.
-define(RA_PROTO_VERSION, 1).
%% the protocol version should be incremented whenever extensions need to be
%% done to the core protocol records (below). It is only ever exchanged by the
%% pre_vote message so that servers can reject pre votes for servers running a
%% higher protocol version. This should be sufficient to disallow a server with
%% newer protocol version to become leader before it has a majority and thus
%% potentially exchange incompatible message types with servers running older
%% code.
%%
%% If fields need to be added to any of the below records it is suggested that
%% a new record is created (by appending _vPROTO_VERSION). The server still need
%% to be able to handle and reply to the older message types to ensure
%% availability.
%% Figure 2 in the paper
-record(append_entries_rpc,
{term :: ra_term(),
leader_id :: ra_server_id(),
leader_commit :: ra_index(),
prev_log_index :: non_neg_integer(),
prev_log_term :: ra_term(),
entries = [] :: [log_entry()]}).
-record(append_entries_reply,
{term :: ra_term(),
success :: boolean(),
% because we aren't doing true rpc we may have multiple append
% entries in flight we need to communicate what we are replying
% to
% because writes are fsynced asynchronously we need to indicate
% the last index seen as well as the last index persisted.
next_index :: ra_index(),
% the last index that has been fsynced to disk
last_index :: ra_index(),
last_term :: ra_term()}).
%% Section 5.2
-record(request_vote_rpc,
{term :: ra_term(),
candidate_id :: ra_server_id(),
last_log_index :: ra_index(),
last_log_term :: ra_index()}).
%% Section 4.2
-record(request_vote_result,
{term :: ra_term(),
vote_granted :: boolean()}).
%% pre-vote extension
-record(pre_vote_rpc,
{version = ?RA_PROTO_VERSION :: non_neg_integer(),
term :: ra_term(),
token :: reference(),
candidate_id :: ra_server_id(),
last_log_index :: ra_index(),
last_log_term :: ra_index()}).
-record(pre_vote_result,
{term :: ra_term(),
token :: reference(),
vote_granted :: boolean()}).
-record(install_snapshot_rpc,
{term :: ra_term(), % the leader's term
leader_id :: ra_server_id(),
% the snapshot replaces all previous entries incl this
last_index :: ra_index(),
% the term at the point of snapshot
last_term :: ra_term(),
last_config :: ra_cluster_servers(),
data :: term()
}).
-record(install_snapshot_result,
{term :: ra_term(),
% because we aren't doing true rpc we may have multiple append
% entries in flight we need to communicate what we are replying
% to
last_index :: ra_index(),
last_term :: ra_term()}).
%% WAL defaults
-define(WAL_MAX_SIZE_BYTES, 1024 * 1024 * 1024).
% primitive logging abstraction
-define(error, true).
-define(warn, true).
-define(info, true).
-ifdef(info).
-define(INFO(Fmt, Args), error_logger:info_msg(Fmt, Args)).
-else.
-define(INFO(_F, _A), ok).
-endif.
-ifdef(warn).
-define(WARN(Fmt, Args), error_logger:warning_msg(Fmt, Args)).
-else.
-define(WARN(_, _), ok).
-endif.
-ifdef(error).
-define(ERR(Fmt, Args), error_logger:error_msg(Fmt, Args)).
-else.
-define(ERR(_, _), ok).
-endif.
-define(DEFAULT_TIMEOUT, 5000).