Documentation
¶
Index ¶
- type AppendEntriesArgs
- type AppendEntriesReply
- type CMState
- type CommitEntry
- type ConfigChangeEntry
- type ConfigChangeType
- type ConsensusModule
- func (cm *ConsensusModule) AddPeer(nodeId int) bool
- func (cm *ConsensusModule) AppendEntries(args AppendEntriesArgs, reply *AppendEntriesReply) error
- func (cm *ConsensusModule) InstallSnapshot(lastIndex, lastTerm int, snapshotData []byte)
- func (cm *ConsensusModule) InstallSnapshotRPC(args InstallSnapshotArgs, reply *InstallSnapshotReply) error
- func (cm *ConsensusModule) RemovePeer(nodeId int) bool
- func (cm *ConsensusModule) Report() (id int, term int, isLeader bool)
- func (cm *ConsensusModule) RequestVote(args RequestVoteArgs, reply *RequestVoteReply) error
- func (cm *ConsensusModule) SnapshotDone() <-chan struct{}
- func (cm *ConsensusModule) SnapshotReady() <-chan SnapshotEntry
- func (cm *ConsensusModule) Stop()
- func (cm *ConsensusModule) Submit(command any) SubmitResult
- type FileStorage
- type Harness
- func (h *Harness) CheckCommitted(cmd int) (nc int, index int)
- func (h *Harness) CheckCommittedAtLeastN(cmd int, n int)
- func (h *Harness) CheckCommittedIgnoringSnapshot(cmd int) (nc int, index int)
- func (h *Harness) CheckCommittedN(cmd int, n int)
- func (h *Harness) CheckNoLeader()
- func (h *Harness) CheckNoSnapshotDelivered(id int)
- func (h *Harness) CheckNotCommitted(cmd int)
- func (h *Harness) CheckSingleLeader() (int, int)
- func (h *Harness) CheckSnapshotDelivered(id int, wantIndex int) SnapshotEntry
- func (h *Harness) CrashPeer(id int)
- func (h *Harness) DisconnectPeer(id int)
- func (h *Harness) PeerDontDropCalls(id int)
- func (h *Harness) PeerDropCallsAfterN(id int, n int)
- func (h *Harness) ReconnectPeer(id int)
- func (h *Harness) RestartPeer(id int)
- func (h *Harness) Shutdown()
- func (h *Harness) SubmitToServer(serverId int, cmd any) int
- func (h *Harness) WaitForStableCommits(n int)
- type InstallSnapshotArgs
- type InstallSnapshotReply
- type LogEntry
- type MapStorage
- type RPCProxy
- func (rpp *RPCProxy) AppendEntries(args AppendEntriesArgs, reply *AppendEntriesReply) error
- func (rpp *RPCProxy) Call(peer *rpc.Client, method string, args any, reply any) error
- func (rpp *RPCProxy) DontDropCalls()
- func (rpp *RPCProxy) DropCallsAfterN(n int)
- func (rpp *RPCProxy) InstallSnapshotRPC(args InstallSnapshotArgs, reply *InstallSnapshotReply) error
- func (rpp *RPCProxy) RequestVote(args RequestVoteArgs, reply *RequestVoteReply) error
- type RequestVoteArgs
- type RequestVoteReply
- type Server
- func (s *Server) AddPeer(nodeId int, addr net.Addr) bool
- func (s *Server) Call(id int, serviceMethod string, args any, reply any) error
- func (s *Server) ConnectToPeer(peerId int, addr net.Addr) error
- func (s *Server) DisconnectAll()
- func (s *Server) DisconnectPeer(peerId int) error
- func (s *Server) GetListenAddr() net.Addr
- func (s *Server) InstallSnapshot(lastIndex, lastTerm int, data []byte)
- func (s *Server) IsLeader() bool
- func (s *Server) Proxy() *RPCProxy
- func (s *Server) RemovePeer(nodeId int) bool
- func (s *Server) Serve()
- func (s *Server) Shutdown()
- func (s *Server) SnapshotDone() <-chan any
- func (s *Server) SnapshotReady() <-chan SnapshotEntry
- func (s *Server) Submit(cmd any) SubmitResult
- type SnapshotEntry
- type Storage
- type SubmitResult
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AppendEntriesArgs ¶
type AppendEntriesReply ¶
type CommitEntry ¶
CommitEntry is the data reported by Raft to the commit channel.
type ConfigChangeEntry ¶
type ConfigChangeEntry struct {
Type ConfigChangeType
NodeId int
}
type ConfigChangeType ¶
type ConfigChangeType int
const ( AddNode ConfigChangeType = iota RemoveNode )
type ConsensusModule ¶
type ConsensusModule struct {
// contains filtered or unexported fields
}
ConsensusModule (CM) implements a single node of Raft consensus.
func NewConsensusModule ¶
func NewConsensusModule( id int, peerIds []int, server *Server, storage Storage, ready <-chan any, commitChan chan<- CommitEntry, logger *slog.Logger, ) *ConsensusModule
func (*ConsensusModule) AddPeer ¶
func (cm *ConsensusModule) AddPeer(nodeId int) bool
AddPeer proposes adding nodeId to the cluster. Must be called on the leader. Returns false if not leader or a config change is already pending.
func (*ConsensusModule) AppendEntries ¶
func (cm *ConsensusModule) AppendEntries(args AppendEntriesArgs, reply *AppendEntriesReply) error
func (*ConsensusModule) InstallSnapshot ¶
func (cm *ConsensusModule) InstallSnapshot(lastIndex, lastTerm int, snapshotData []byte)
InstallSnapshot is called by the application layer (or test harness) to compact the log. snapshotData is an opaque blob that fully encodes the application state as of lastIndex/lastTerm.
func (*ConsensusModule) InstallSnapshotRPC ¶
func (cm *ConsensusModule) InstallSnapshotRPC(args InstallSnapshotArgs, reply *InstallSnapshotReply) error
InstallSnapshotRPC is the RPC handler called on a follower by the leader when the follower's nextIndex has fallen behind the leader's snapshot point.
func (*ConsensusModule) RemovePeer ¶
func (cm *ConsensusModule) RemovePeer(nodeId int) bool
RemovePeer proposes removing nodeId from the cluster. Must be called on the leader.
func (*ConsensusModule) Report ¶
func (cm *ConsensusModule) Report() (id int, term int, isLeader bool)
func (*ConsensusModule) RequestVote ¶
func (cm *ConsensusModule) RequestVote(args RequestVoteArgs, reply *RequestVoteReply) error
func (*ConsensusModule) SnapshotDone ¶
func (cm *ConsensusModule) SnapshotDone() <-chan struct{}
SnapshotDone returns a channel that is closed when the CM is stopped. Use it to terminate goroutines that drain SnapshotReady().
func (*ConsensusModule) SnapshotReady ¶
func (cm *ConsensusModule) SnapshotReady() <-chan SnapshotEntry
SnapshotReady returns the channel on which snapshot notifications arrive. The application should drain this channel and restore its state machine. The channel is never closed; watch SnapshotDone() to know when to stop.
func (*ConsensusModule) Stop ¶
func (cm *ConsensusModule) Stop()
func (*ConsensusModule) Submit ¶
func (cm *ConsensusModule) Submit(command any) SubmitResult
Submit submits a new command to the CM.
type FileStorage ¶
type FileStorage struct {
// contains filtered or unexported fields
}
FileStorage is a durable Storage implementation that writes each key to its own file under a directory. Writes are atomic: data is first flushed to a temp file in the same directory, then renamed over the target, so a crash mid-write never leaves a partially-written value behind.
func NewFileStorage ¶
func NewFileStorage(dir string) (*FileStorage, error)
NewFileStorage creates (or opens) a FileStorage rooted at dir. The directory is created with 0700 permissions if it does not exist.
func (*FileStorage) Get ¶
func (fs *FileStorage) Get(key string) ([]byte, bool)
Get retrieves the value for key. Returns (nil, false) if the key has never been Set; panics on unexpected I/O errors.
func (*FileStorage) HasData ¶
func (fs *FileStorage) HasData() bool
HasData returns true if the storage directory contains at least one .dat file, meaning at least one Set has been persisted to disk.
func (*FileStorage) Set ¶
func (fs *FileStorage) Set(key string, value []byte)
Set writes value for key atomically. Panics (like MapStorage) on I/O error so callers don't have to check — a storage failure is fatal for Raft anyway.
type Harness ¶
type Harness struct {
// contains filtered or unexported fields
}
func NewHarness ¶
NewHarness creates a new test Harness, initialized with n servers connected to each other.
func (*Harness) CheckCommitted ¶
CheckCommitted verifies that all connected servers have cmd committed with the same index. It also verifies that all commands *before* cmd in the commit sequence match. For this to work properly, all commands submitted to Raft should be unique positive ints. Returns the number of servers that have this command committed, and its log index.
func (*Harness) CheckCommittedAtLeastN ¶
CheckCommittedAtLeastN verifies that cmd was committed by at least n connected servers. Use this when a newly-joined server may have replayed historical entries, making the exact count uncertain.
func (*Harness) CheckCommittedIgnoringSnapshot ¶
CheckCommittedIgnoringSnapshot is like CheckCommitted but does NOT require that all connected servers have the same length commits slice. This is needed after a snapshot: a restarted server will have had its log replaced by the snapshot and will only report the post-snapshot commits, while servers that were never restarted show the full history.
Instead of a length equality check it simply looks for cmd in each connected server's commits slice and verifies that wherever it appears it has the same index.
func (*Harness) CheckCommittedN ¶
CheckCommittedN verifies that cmd was committed by exactly n connected servers.
func (*Harness) CheckNoLeader ¶
func (h *Harness) CheckNoLeader()
CheckNoLeader checks that no connected server considers itself the leader.
func (*Harness) CheckNoSnapshotDelivered ¶
CheckNoSnapshotDelivered asserts that server id has received no snapshots yet.
func (*Harness) CheckNotCommitted ¶
CheckNotCommitted verifies that no command equal to cmd has been committed by any of the active servers yet.
func (*Harness) CheckSingleLeader ¶
CheckSingleLeader checks that only a single server thinks it's the leader. Returns the leader's id and term. It retries several times if no leader is identified yet.
func (*Harness) CheckSnapshotDelivered ¶
func (h *Harness) CheckSnapshotDelivered(id int, wantIndex int) SnapshotEntry
snapshot whose Index equals wantIndex, then returns that snapshot. It fails the test if no such snapshot arrives within ~5 seconds.
func (*Harness) CrashPeer ¶
CrashPeer "crashes" a server by disconnecting it from all peers and then asking it to shut down. We're not going to use the same server instance again, but its storage is retained.
func (*Harness) DisconnectPeer ¶
DisconnectPeer disconnects a server from all other servers in the cluster.
func (*Harness) PeerDontDropCalls ¶
PeerDontDropCalls instructs peer `id` to stop dropping calls.
func (*Harness) PeerDropCallsAfterN ¶
PeerDropCallsAfterN instructs peer `id` to drop calls after the next `n` are made.
func (*Harness) ReconnectPeer ¶
ReconnectPeer connects a server to all other servers in the cluster.
func (*Harness) RestartPeer ¶
RestartPeer "restarts" a server by creating a new Server instance and giving it the appropriate storage, reconnecting it to peers.
func (*Harness) Shutdown ¶
func (h *Harness) Shutdown()
Shutdown shuts down all the servers in the harness and waits for them to stop running.
func (*Harness) SubmitToServer ¶
SubmitToServer submits the command to serverId.
func (*Harness) WaitForStableCommits ¶
WaitForStableCommits polls until every connected server has committed at least n integer entries, or until ~2 s elapses. It does not fail on its own — callers should use CheckCommittedN / CheckCommittedAtLeastN after returning to verify consistency. Useful under RAFT_UNRELIABLE_RPC where commit-index heartbeats can be delayed or dropped.
type InstallSnapshotArgs ¶
type InstallSnapshotReply ¶
type InstallSnapshotReply struct {
Term int
}
type MapStorage ¶
type MapStorage struct {
// contains filtered or unexported fields
}
MapStorage is a simple in-memory implementation of Storage for testing.
func NewMapStorage ¶
func NewMapStorage() *MapStorage
func (*MapStorage) HasData ¶
func (ms *MapStorage) HasData() bool
func (*MapStorage) Set ¶
func (ms *MapStorage) Set(key string, value []byte)
type RPCProxy ¶
type RPCProxy struct {
// contains filtered or unexported fields
}
func NewProxy ¶
func NewProxy(cm *ConsensusModule) *RPCProxy
func (*RPCProxy) AppendEntries ¶
func (rpp *RPCProxy) AppendEntries(args AppendEntriesArgs, reply *AppendEntriesReply) error
func (*RPCProxy) DontDropCalls ¶
func (rpp *RPCProxy) DontDropCalls()
func (*RPCProxy) DropCallsAfterN ¶
func (*RPCProxy) InstallSnapshotRPC ¶
func (rpp *RPCProxy) InstallSnapshotRPC(args InstallSnapshotArgs, reply *InstallSnapshotReply) error
func (*RPCProxy) RequestVote ¶
func (rpp *RPCProxy) RequestVote(args RequestVoteArgs, reply *RequestVoteReply) error
type RequestVoteArgs ¶
type RequestVoteReply ¶
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
func (*Server) AddPeer ¶
AddPeer adds nodeId to the cluster via a ConfigChange log entry. addr is the RPC address of the new node; this server will connect to it.
func (*Server) DisconnectAll ¶
func (s *Server) DisconnectAll()
func (*Server) DisconnectPeer ¶
func (*Server) GetListenAddr ¶
func (*Server) InstallSnapshot ¶
InstallSnapshot tells the ConsensusModule to compact the log up to lastIndex / lastTerm using the provided application snapshot data. This is the application-initiated path (as opposed to the leader-push path via InstallSnapshotRPC).
func (*Server) RemovePeer ¶
RemovePeer removes nodeId from the cluster via a ConfigChange log entry.
func (*Server) SnapshotDone ¶
SnapshotDone returns a channel that is closed when this Server is shut down via Shutdown(). It is the same channel that terminates the RPC accept loop, so callers are guaranteed to observe the close at most once after Shutdown returns. Use it to terminate goroutines that drain SnapshotReady().
func (*Server) SnapshotReady ¶
func (s *Server) SnapshotReady() <-chan SnapshotEntry
SnapshotReady returns the channel on which the ConsensusModule delivers SnapshotEntry values when a snapshot is installed by the leader. The application must drain this channel and restore its state machine.
func (*Server) Submit ¶
func (s *Server) Submit(cmd any) SubmitResult
type SnapshotEntry ¶
SnapshotEntry is sent on the commit channel when a snapshot is installed. The application must restore its state from Data and discard all previously applied entries up through Index.
type Storage ¶
type Storage interface {
Set(key string, value []byte)
Get(key string) ([]byte, bool)
// HasData returns true iff any Sets were made on this Storage.
HasData() bool
}
Storage is an interface implemented by stable storage providers.
type SubmitResult ¶
SubmitResult is returned by Submit.