rafted_value v0.1.10 RaftedValue

Public interface functions of RaftedValue package.

Summary

Functions

Replaces the current configuration

Executes a command on the stored value of leader

Tell a member to forget about another member

Executes a read-only query on the stored value of leader

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

Types

command_identifier()
command_identifier() :: reference | any
consensus_group_info()
consensus_group_info ::
  {:create_new_consensus_group, RaftedValue.Config.t} |
  {:join_existing_consensus_group, [GenServer.server]}
not_leader()
not_leader() :: {:not_leader, nil | pid}
remove_follower_error_reason()
remove_follower_error_reason ::
  not_leader |
  :uncommitted_membership_change |
  :not_member |
  :pending_leader_change |
  :cannot_remove_leader |
  :will_break_quorum
replace_leader_error_reason()
replace_leader_error_reason ::
  not_leader |
  :uncommitted_membership_change |
  :not_member |
  :new_leader_unresponsive
status_result()
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}

Functions

change_config(leader, new_config)
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(leader, command_arg, timeout \\ 5000, id \\ make_ref())
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(member, member_to_remove)
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(data_module, opts \\ [])
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 of RaftedValue.LeaderHook. Defaults to RaftedValue.LeaderHook.NoOp.
  • communication_module: A module to define member-to-member async communication (send_event/2 and reply/2). Defaults to RaftedValue.RemoteMessageGateway. This is configurable for internal testing purpose.
  • heartbeat_timeout: Raft’s heartbeat timeout in milliseconds. Defaults to 200.
  • election_timeout: Raft’s leader election timeout in milliseconds. The acrual timeout value in each member is randomly chosen from election_timeout .. 2 * election_timeout. Defaults to 1000.
  • 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 for election_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 of election_timeout (i.e. no lease time, disabling this clock-based optimization).
  • max_retained_committed_logs: Number of committed log entries to keep in each member. Defaults to 100.
  • max_retained_command_results: Number of command results to be cached, in order to prevent doubly applying the same command. Defaults to 100.
query(leader, query_arg, timeout \\ 5000)
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)).

remove_follower(leader, follower_pid)
remove_follower(GenServer.server, pid) ::
  :ok |
  {:error, remove_follower_error_reason}

Removes a follower from a consensus group.

replace_leader(current_leader, new_leader)
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(info, name_or_nil \\ nil)

Starts a new member of consensus group.

The 1st argument specifies the consensus group to belong to:

  • {:create_new_consensus_group, Config.t}: Creates a new consensus group using the given Config.t. The group’s only member is the newly-created process and it is spawned as the leader.
  • {:join_existing_consensus_group, [servers]}: Joins an already running consensus grouop as a new follower.

The second argument is (if given) used for name registration.

status(server)

Retrieves status of a member in a consensus group.