1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
//! Inputs to the consensus state machine.
use crate::kraft::types::{LeaderEpoch, NodeId};
/// A peer's view of its log tip, carried in Vote/Fetch requests.
#[derive(Debug, Clone, Copy)]
pub struct LogEnd {
pub last_epoch: LeaderEpoch,
pub last_offset: i64,
}
#[derive(Debug, Clone)]
pub enum Event {
/// The election timer fired.
ElectionTimeout,
/// The fetch timer fired (follower/observer lost contact with the leader).
FetchTimeout,
/// A peer asks us for our vote.
ReceiveVoteRequest {
from: NodeId,
/// The recipient this Vote is addressed to (the wire top-level
/// `voterId`). KIP-595 / Kafka's `KafkaRaftClient` validates that an
/// incoming Vote targets this node before considering the grant; a
/// request addressed to a different voter is rejected.
voter_id: NodeId,
candidate_epoch: LeaderEpoch,
candidate: NodeId,
candidate_log_end: LogEnd,
pre_vote: bool,
},
/// A peer answered our Vote. The round (pre-vote vs real vote) is NOT on the
/// wire — the candidate infers it from its own `Prospective`/`Candidate`
/// role + epoch (KIP-996; mirrors Kafka's field-less `VoteResponse`).
ReceiveVoteResponse {
from: NodeId,
epoch: LeaderEpoch,
vote_granted: bool,
},
/// A leader announces its epoch to us.
ReceiveBeginQuorumEpoch {
leader_id: NodeId,
leader_epoch: LeaderEpoch,
},
/// A resigning leader tells us to start an election.
ReceiveEndQuorumEpoch {
leader_id: NodeId,
leader_epoch: LeaderEpoch,
},
/// (Leader side) a follower fetched at this position.
ReceiveFetch {
from: NodeId,
fetch_epoch: LeaderEpoch,
fetch_offset: i64,
},
/// (Follower side) the leader answered our Fetch.
ReceiveFetchResponse {
leader_id: NodeId,
leader_epoch: LeaderEpoch,
/// Set when the leader signalled log divergence.
diverging: Option<crate::kraft::types::LogOffsetMetadata>,
},
}