rafted_value v0.5.0 RaftedValue View Source
Public interface functions of RaftedValue
package.
Link to this section Summary
Functions
Replaces the current configuration
Executes a command on the stored value of leader
Tell a member to forget about another member
Make a new instance of RaftedValue.Config
struct
Executes a read-only query on the stored value of leader
Obtains last log index from the log files stored in dir
Removes a follower from a consensus group
Replaces current leader of a consensus group from current_leader
to new_leader
Starts a new member of consensus group
Retrieves status of a member in a consensus group
Link to this section Types
consensus_group_info :: {:create_new_consensus_group, RaftedValue.Config.t} | {:join_existing_consensus_group, [GenServer.server]}
remove_follower_error_reason :: not_leader | :uncommitted_membership_change | :not_member | :pending_leader_change | :cannot_remove_leader | :will_break_quorum
replace_leader_error_reason :: not_leader | :uncommitted_membership_change | :not_member | :new_leader_unresponsive
status_result() :: %{from: pid, members: [pid], leader: nil | pid, unresponsive_followers: [pid], current_term: RaftedValue.TermNumber.t, state_name: :leader | :candidate | :follower, config: RaftedValue.Config.t}
Link to this section Functions
change_config(GenServer.server, RaftedValue.Config.t) :: :ok | {:error, not_leader}
Replaces the current configuration.
The new configuration is replicated (as raft log) to all members.
command(GenServer.server, RaftedValue.Data.command_arg, timeout, command_identifier) :: {:ok, RaftedValue.Data.command_ret} | {:error, :noproc | :timeout | not_leader}
Executes a command on the stored value of leader
.
id
is an identifier of the command and can be used to filter out duplicate requests.
If the leader does not respond in a timely manner, the function returns {:error, :timeout}
, i.e., it internally catches exit.
Caller process should be prepared to handle delayed reply
(e.g. by dropping delayed reply by handle_info(_msg, state)
).
force_remove_member(GenServer.server, pid) :: :ok | {:error, :leader_exists}
Tell a member to forget about another member.
The sole purpose of this function is to recover a consensus group from majority failure.
This operation is unsafe in the sense that it may not preserve invariants of the Raft algorithm
(for example some committed logs may be lost); use this function as a last resort.
When the receiver process thinks that there exists a valid leader, it rejects with :leader_exists
.
Membership change introduced by this function is not propagated to other members. It is caller’s responsibility to notify all existing members of the membership change.
make_config(atom, Keyword.t(any)) :: RaftedValue.Config.t
Make a new instance of RaftedValue.Config
struct.
data_module
must be an implementation of RaftedValue.Data
behaviour.
Available options:
leader_hook_module
: An implementation ofRaftedValue.LeaderHook
. Defaults toRaftedValue.LeaderHook.NoOp
.communication_module
: A module to define member-to-member async communication (send_event/2
andreply/2
). Defaults toRaftedValue.RemoteMessageGateway
. This is configurable for internal testing purpose.heartbeat_timeout
: Raft’s heartbeat timeout in milliseconds. Defaults to200
.election_timeout
: Raft’s leader election timeout in milliseconds. The acrual timeout value in each member is randomly chosen fromelection_timeout .. 2 * election_timeout
. Defaults to1000
.election_timeout_clock_drift_margin
: A time margin in milliseconds to judge whether leader lease has expired or not. When a leader gets responses from majority it gets a lease forelection_timeout - margin
. During the lease time the leader can assume that no other members are ever elected leader. This enables the leader to skip message round trips during processing read-only query. Defaults to the value ofelection_timeout
(i.e. no lease time, disabling this clock-based optimization).max_retained_command_results
: Number of command results to be cached, in order not to doubly apply the same command due to client retries. Defaults to100
.
query(GenServer.server, RaftedValue.Data.query_arg, timeout) :: {:ok, RaftedValue.Data.query_ret} | {:error, :noproc | :timeout | not_leader}
Executes a read-only query on the stored value of leader
.
If the leader does not respond in a timely manner, the function returns {:error, :timeout}
, i.e., it internally catches exit.
Caller process should be prepared to handle delayed reply
(e.g. by dropping delayed reply by handle_info(_msg, state)
).
read_last_log_index(Path.t) :: nil | RaftedValue.LogIndex.t
Obtains last log index from the log files stored in dir
.
remove_follower(GenServer.server, pid) :: :ok | {:error, remove_follower_error_reason}
Removes a follower from a consensus group.
replace_leader(GenServer.server, nil | pid) :: :ok | {:error, replace_leader_error_reason}
Replaces current leader of a consensus group from current_leader
to new_leader
.
start_link(consensus_group_info, [option]) :: GenServer.on_start
Starts a new member of consensus group.
The 1st argument specifies the consensus group to belong to:
{:create_new_consensus_group, config}
: Creates a new consensus group using the givenRaftedValue.Config.t
. The group’s only member is the newly-created process and it immediately becomes a leader.{:join_existing_consensus_group, [member]}
: Joins an already running consensus group as a follower.
The 2nd argument is a keyword list of options to specify member-specific configurations.
:name
: An atom for local name registration.:persistence_dir
: Directory path in which both Raft logs and periodic snapshots are stored. If not given, the newly-spawned process will run in in-memory mode; it does not persist its state. The specified directory will be created if it does not exist. Note that it’s caller’s responsibility to ensure that the specified directory is not used by otherRaftedValue
process. See below for details of restoring state from snapshot and logs.:log_file_expansion_factor
: A number that adjusts when to make a snapshot file. This does not take effect if:persistence_dir
is not given.RaftedValue
keeps track of the file sizes of “currently growing log file” and “previous snapshot file”. A new snapshot is created whenlog_file_size > previous_snapshot_size * expansion_factor
. Small value means frequent snapshotting, which can result in high overhead. On the other hand larger expansion factor may lead to longer recovery time. Defaults to10
.
For backward compatibility, passing a non-nil
atom as 2nd argument is interpreted as [name: name_atom]
.
This behavior will be removed in a future release.
Restoring state from snapshot and log files
RaftedValue
implements state recovery using log and snapshot files.
The recovery procedure is triggered when:
- A new process is
start_link
ed with{:create_new_consensus_group, config}
and:persistence_dir
. - Valid log and snapshot files exist in the given
:persistence_dir
.
Then the newly-spawned process loads the latest snapshot and log files and forms a new 1-member consensus group
with the restored Raft state (except for membership information).
When restoring from snapshot and logs, config
passed in the 1st argument is neglected in favor of configurations in the snapshot and logs.
If you don’t want to restore from snapshot and log files (i.e. want to start a consensus group from scratch),
then you must clean up the directory before calling start_link/2
.
status(GenServer.server, timeout) :: status_result
Retrieves status of a member in a consensus group.