[−][src]Struct actix_raft::messages::AppendEntriesRequest
An RPC invoked by the leader to replicate log entries (§5.3); also used as heartbeat (§5.2).
actix::Message
Applications using this Raft implementation are responsible for implementing the
networking/transport layer which must move RPCs between nodes. Once the application instance
recieves a Raft RPC, it must send the RPC to the Raft node via its actix::Addr
and then
return the response to the original sender.
The result type of calling the Raft actor with this message type is
Result<AppendEntriesResponse, ()>
. The Raft spec assigns no significance to failures during
the handling or sending of RPCs and all RPCs are handled in an idempotent fashion, so Raft
will almost always retry sending a failed RPC, depending on the state of the Raft.
Fields
target: u64
A non-standard field, this is the ID of the intended recipient of this RPC.
term: u64
The leader's current term.
leader_id: u64
The leader's ID. Useful in redirecting clients.
prev_log_index: u64
The index of the log entry immediately preceding the new entries.
prev_log_term: u64
The term of the prev_log_index
entry.
entries: Vec<Entry<D>>
The new log entries to store.
This may be empty when the leader is sending heartbeats. Entries may be batched for efficiency.
leader_commit: u64
The leader's commit index.
Trait Implementations
impl<D: Debug + AppData> Debug for AppendEntriesRequest<D>
[src]
impl<'de, D: AppData> Deserialize<'de> for AppendEntriesRequest<D> where
D: AppData,
[src]
D: AppData,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error> where
__D: Deserializer<'de>,
[src]
__D: Deserializer<'de>,
impl<D: AppData, R: AppDataResponse, E: AppError, N: RaftNetwork<D>, S: RaftStorage<D, R, E>> Handler<AppendEntriesRequest<D>> for Raft<D, R, E, N, S>
[src]
type Result = ResponseActFuture<Self, AppendEntriesResponse, ()>
The type of value that this handler will return.
fn handle(
&mut self,
msg: AppendEntriesRequest<D>,
ctx: &mut Self::Context
) -> Self::Result
[src]
&mut self,
msg: AppendEntriesRequest<D>,
ctx: &mut Self::Context
) -> Self::Result
An RPC invoked by the leader to replicate log entries (§5.3); also used as heartbeat (§5.2).
This method implements the append entries algorithm and upholds all of the safety checks detailed in §5.3.
Implementation overview from spec:
- Reply
false
ifterm
is less than node's currentterm
(§5.1). - Reply
false
if log doesn’t contain an entry atprev_log_index
whose term matchesprev_log_term
(§5.3). - If an existing entry conflicts with a new one (same index but different terms), delete the existing entry and all that follow it (§5.3).
- Append any new entries not already in the log.
- If
leader_commit
is greater than node's commit index, set nodes commit index tomin(leader_commit, index of last new entry)
.
The essential goal of this algorithm is that the receiver (the node on which this method is being executed) must find the exact entry in its log specified by the RPC's last index and last term fields, and then begin writing the new entries thereafter.
When the receiver can not find the entry specified in the RPC's prev index & prev term
fields, it will respond with a failure to the leader. This implementation of Raft
includes the conflicting term optimization which is intended to reduce the number of
rejected append entries RPCs from followers which are lagging behind, which is detailed in
§5.3. In such cases, if the Raft cluster is configured with a snapshot policy other than
Disabled
, the leader will make a determination if an InstallSnapshot
RPC should be
sent to this node.
In Raft, the leader handles inconsistencies by forcing the followers’ logs to duplicate its own. This means that conflicting entries in follower logs will be overwritten with entries from the leader’s log. §5.4 details the safety of this protocol. It is important to note that logs which are committed will not be overwritten. This is a critical feature of Raft.
Raft also gurantees that only logs which have been comitted may be applied to the state machine, which ensures that there will never be a case where a log needs to be reverted after being applied to the state machine.
inconsistency example
Followers may receive valid append entries requests from leaders, append them, respond, and before the leader is able to replicate the entries to a majority of nodes, the leader may die, a new leader may be elected which does not have the same entries, as they were not replicated to a majority of followers, and the new leader will proceeed to overwrite the inconsistent entries.
impl<D: AppData> Message for AppendEntriesRequest<D>
[src]
type Result = Result<AppendEntriesResponse, ()>
The result type of this message.
The Result::Err
type is ()
as Raft assigns no significance to RPC failures, they will
be retried almost always as long as permitted by the current state of the Raft.
impl<D: AppData> Serialize for AppendEntriesRequest<D> where
D: AppData,
[src]
D: AppData,
Auto Trait Implementations
impl<D> RefUnwindSafe for AppendEntriesRequest<D> where
D: RefUnwindSafe,
D: RefUnwindSafe,
impl<D> Send for AppendEntriesRequest<D>
impl<D> Sync for AppendEntriesRequest<D>
impl<D> Unpin for AppendEntriesRequest<D> where
D: Unpin,
D: Unpin,
impl<D> UnwindSafe for AppendEntriesRequest<D> where
D: UnwindSafe,
D: UnwindSafe,
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> DeserializeOwned for T where
T: for<'de> Deserialize<'de>,
[src]
T: for<'de> Deserialize<'de>,
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,
type Error = <U as TryFrom<T>>::Error
The type returned in the event of a conversion error.
fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>
[src]
impl<V, T> VZip<V> for T where
V: MultiLane<T>,
V: MultiLane<T>,