aarondb/raft
raft — INACTIVE clustering scaffold (unwired stub)
⚠️ STATUS: A complete, pure, unit-tested leader-election state machine, now unwired from the engine. The single-node AaronDB core no longer holds, initialises, or drives any raft state:
DbStateno longer has araft_statefield.- The transactor has no
RaftMsgvariant and never callshandle_message. aarondb.is_leaderhas been removed.
SCOPE: This is Raft election only. The log-replication half (AppendEntries, commit index, log matching, apply) was never present, so it could not deliver replicated consistency on its own.
The pure protocol logic is sound and covered by test/aarondb/raft_test.
It is retained as a deliberate, documented stub — a clustering seed, not
active code. To revive: design a transport + peer config, add the missing
replication half, and re-introduce a raft field on DbState.
Types
Effects emitted after a state transition (data, not side effects). This de-complects the pure state machine from side effects.
pub type RaftEffect {
SendHeartbeat(to: process.Pid, term: Int, leader: process.Pid)
SendVoteRequest(
to: process.Pid,
term: Int,
candidate: process.Pid,
)
SendVoteResponse(to: process.Pid, term: Int, granted: Bool)
RegisterAsLeader
UnregisterAsLeader
ResetElectionTimer
StartHeartbeatTimer
StopHeartbeatTimer
}
Constructors
-
SendHeartbeat(to: process.Pid, term: Int, leader: process.Pid) -
SendVoteRequest( to: process.Pid, term: Int, candidate: process.Pid, ) -
SendVoteResponse(to: process.Pid, term: Int, granted: Bool) -
RegisterAsLeader -
UnregisterAsLeader -
ResetElectionTimer -
StartHeartbeatTimer -
StopHeartbeatTimer
Messages the Raft state machine can process.
pub type RaftMessage {
Heartbeat(term: Int, leader: process.Pid)
HeartbeatResponse(term: Int, from: process.Pid)
VoteRequest(term: Int, candidate: process.Pid)
VoteResponse(term: Int, granted: Bool, from: process.Pid)
ElectionTimeout
HeartbeatTick
}
Constructors
-
Heartbeat(term: Int, leader: process.Pid) -
HeartbeatResponse(term: Int, from: process.Pid) -
VoteRequest(term: Int, candidate: process.Pid) -
VoteResponse(term: Int, granted: Bool, from: process.Pid) -
ElectionTimeout -
HeartbeatTick
The three roles in Raft’s election protocol.
pub type RaftRole {
Follower
Candidate
Leader
}
Constructors
-
Follower -
Candidate -
Leader
The pure state of the Raft election state machine. No side effects — the transactor interprets the effects.
pub type RaftState {
RaftState(
role: RaftRole,
current_term: Int,
voted_for: option.Option(process.Pid),
peers: List(process.Pid),
votes_received: Int,
leader_pid: option.Option(process.Pid),
)
}
Constructors
-
RaftState( role: RaftRole, current_term: Int, voted_for: option.Option(process.Pid), peers: List(process.Pid), votes_received: Int, leader_pid: option.Option(process.Pid), )
Values
pub fn add_peer(state: RaftState, peer: process.Pid) -> RaftState
Add a peer to the cluster.
pub fn handle_message(
state: RaftState,
msg: RaftMessage,
self_pid: process.Pid,
) -> #(RaftState, List(RaftEffect))
Process a Raft message and return the new state + effects. This is the ONLY entry point. It is pure — no side effects.
pub fn new(peers: List(process.Pid)) -> RaftState
Create a new Raft state in Follower role at term 0.
pub fn remove_peer(
state: RaftState,
peer: process.Pid,
) -> RaftState
Remove a peer from the cluster.