Documentation
¶
Overview ¶
Core Raft implementation - Consensus Module.
Eli Bendersky [https://eli.thegreenplace.net] This code is in the public domain. Maintained By : Rukshan Perera [https://www.krvperera.com]
Server container for a Raft Consensus Module. Exposes Raft to the network and enables RPCs between Raft peers.
Eli Bendersky [https://eli.thegreenplace.net] This code is in the public domain.
Eli Bendersky [https://eli.thegreenplace.net] This code is in the public domain. Maintained by : Rukshan Perera (rukshan.perera@student.oulu.fi)
Test harness for writing tests for Raft.
Eli Bendersky [https://eli.thegreenplace.net] This code is in the public domain.
Index ¶
- Constants
- type AppendEntriesArgs
- type AppendEntriesReply
- type BaseHarness
- type CommitEntry
- type ConsensusModule
- func (cm *ConsensusModule) AppendEntries(args AppendEntriesArgs, reply *AppendEntriesReply) error
- func (cm *ConsensusModule) EvaluationDump(format string, args ...interface{})
- func (cm *ConsensusModule) Report() (id int, term int, isLeader bool)
- func (cm *ConsensusModule) RequestVote(args RequestVoteArgs, reply *RequestVoteReply) error
- func (cm *ConsensusModule) Stop()
- func (cm *ConsensusModule) Submit(command interface{}) bool
- type Harness
- func (h *Harness) CheckCommitted(cmd int) (nc int, index int)
- func (h *Harness) CheckCommittedN(cmd int, n int)
- func (h *Harness) CheckNoLeader()
- func (h *Harness) CheckNotCommitted(cmd int)
- func (h *Harness) CheckSingleLeader() (int, int)
- func (h *Harness) CrashPeer(id int)
- func (h *Harness) DisconnectPeer(id int)
- func (h *Harness) ReconnectPeer(id int)
- func (h *Harness) RestartPeer(id int)
- func (h *Harness) Shutdown()
- func (h *Harness) SubmitToServer(serverId int, cmd interface{}) bool
- type LogEntry
- type MapStorage
- type RPCProxy
- type RaftNodeState
- type RequestVoteArgs
- type RequestVoteReply
- type SQLiteStorage
- type Server
- func (s *Server) Call(id int, serviceMethod string, args interface{}, reply interface{}) error
- func (s *Server) ConnectToPeer(peerId int, addr net.Addr) error
- func (s *Server) ConnectToPeerStringAddress(peerId int, addr string) error
- func (s *Server) DisconnectAll()
- func (s *Server) DisconnectPeer(peerId int) error
- func (s *Server) GetListenAddr() net.Addr
- func (s *Server) Serve(address string)
- func (s *Server) Shutdown()
- func (s *Server) Submit(command interface{}) bool
- type SqliteHarness
- func (h *SqliteHarness) CheckNoLeader()
- func (h *SqliteHarness) CheckSingleLeader() (int, int)
- func (h *SqliteHarness) CrashPeer(id int)
- func (h *SqliteHarness) DisconnectPeer(id int)
- func (h *SqliteHarness) ReconnectPeer(id int)
- func (h *SqliteHarness) Shutdown()
- func (h *SqliteHarness) SubmitToServer(serverId int, cmd interface{}) bool
- type Storage
Constants ¶
const DebugCM = 0
const EvalCM = 1
const InfoCM = 0
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AppendEntriesArgs ¶
type AppendEntriesArgs struct {
Term int
LeaderId int
PrevLogIndex int
PrevLogTerm int
Entries []LogEntry
LeaderCommit int
}
See figure 2 in the paper.
type AppendEntriesReply ¶
type BaseHarness ¶
type BaseHarness interface {
Shutdown()
}
type CommitEntry ¶
type CommitEntry struct {
// Command is the client command being committed.
Command interface{}
// Index is the log index at which the client command is committed.
Index int
// Term is the Raft term at which the client command is committed.
Term int
}
CommitEntry is the data reported by Raft to the commit channel. Each commit entry notifies the client that consensus was reached on a command and it can be applied to the client's state machine.
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 interface{}, commitChan chan<- CommitEntry) *ConsensusModule
NewConsensusModule creates a new CM with the given ID, list of peer IDs and server. The ready channel signals the CM that all peers are connected and it's safe to start its state machine. commitChan is going to be used by the CM to send log entries that have been committed by the Raft cluster.
func (*ConsensusModule) AppendEntries ¶
func (cm *ConsensusModule) AppendEntries(args AppendEntriesArgs, reply *AppendEntriesReply) error
func (*ConsensusModule) EvaluationDump ¶
func (cm *ConsensusModule) EvaluationDump(format string, args ...interface{})
func (*ConsensusModule) Report ¶
func (cm *ConsensusModule) Report() (id int, term int, isLeader bool)
Report reports the state of this CM.
func (*ConsensusModule) RequestVote ¶
func (cm *ConsensusModule) RequestVote(args RequestVoteArgs, reply *RequestVoteReply) error
RequestVote RPC.
func (*ConsensusModule) Stop ¶
func (cm *ConsensusModule) Stop()
Stop stops this CM, cleaning up its state. This method returns quickly, but it may take a bit of time (up to ~election timeout) for all goroutines to exit.
func (*ConsensusModule) Submit ¶
func (cm *ConsensusModule) Submit(command interface{}) bool
Submit submits a new command to the CM. This function doesn't block; clients read the commit channel passed in the constructor to be notified of new committed entries. It returns true iff this CM is the leader - in which case the command is accepted. If false is returned, the client will have to find a different CM to submit this command to.
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. TODO: this check may be too strict. Consider tha a server can commit something and crash before notifying the channel. It's a valid commit but this checker will fail because it may not match other servers. This scenario is described in the paper...
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) 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) 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) 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.
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
}
RPCProxy is a trivial pass-thru proxy type for ConsensusModule's RPC methods. It's useful for:
- Simulating a small delay in RPC transmission.
- Avoiding running into https://github.com/golang/go/issues/19957
- Simulating possible unreliable connections by delaying some messages significantly and dropping others when RAFT_UNRELIABLE_RPC is set.
func (*RPCProxy) AppendEntries ¶
func (rpp *RPCProxy) AppendEntries(args AppendEntriesArgs, reply *AppendEntriesReply) error
func (*RPCProxy) RequestVote ¶
func (rpp *RPCProxy) RequestVote(args RequestVoteArgs, reply *RequestVoteReply) error
type RaftNodeState ¶
type RaftNodeState int
const ( Follower RaftNodeState = iota Candidate Leader Dead )
func (RaftNodeState) String ¶
func (s RaftNodeState) String() string
type RequestVoteArgs ¶
type RequestVoteArgs struct {
Term int // candidate's term
CandidateId int // candidate requesting vote
LastLogIndex int // index of candidate's last log entry
LastLogTerm int // term of candidate's last log entry
}
See figure 2 in the paper.
type RequestVoteReply ¶
type SQLiteStorage ¶
type SQLiteStorage struct {
// contains filtered or unexported fields
}
SQLiteStorage is an implementation of Storage using SQLite.
func NewSQLiteStorage ¶
func NewSQLiteStorage(dbPath string) *SQLiteStorage
func (*SQLiteStorage) Close ¶
func (ss *SQLiteStorage) Close() error
Close closes the SQLite database connection.
func (*SQLiteStorage) Get ¶
func (ss *SQLiteStorage) Get(key string) ([]byte, bool)
Get retrieves the value associated with the given key from the SQLite database.
func (*SQLiteStorage) HasData ¶
func (ss *SQLiteStorage) HasData() bool
HasData checks if there is any data stored in the SQLite database.
func (*SQLiteStorage) Set ¶
func (ss *SQLiteStorage) Set(key string, value []byte)
Set stores the given key-value pair in the SQLite database.
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server wraps a raft.ConsensusModule along with a rpc.Server that exposes its methods as RPC endpoints. It also manages the peers of the Raft server. The main goal of this type is to simplify the code of raft.Server for presentation purposes. raft.ConsensusModule has a *Server to do its peer communication and doesn't have to worry about the specifics of running an RPC server.
func NewServer ¶
func NewServer(serverId int, peerIds []int, storage Storage, ready <-chan interface{}, commitChan chan<- CommitEntry) *Server
func (*Server) ConnectToPeerStringAddress ¶
Connect to peers using string address exponential bcakoff is used to connect to peer
func (*Server) DisconnectAll ¶
func (s *Server) DisconnectAll()
DisconnectAll closes all the client connections to peers for this server.
func (*Server) DisconnectPeer ¶
DisconnectPeer disconnects this server from the peer identified by peerId.
func (*Server) GetListenAddr ¶
type SqliteHarness ¶
type SqliteHarness struct {
// contains filtered or unexported fields
}
func NewSQliteDBHarness ¶
func NewSQliteDBHarness(t *testing.T, n int) *SqliteHarness
NewHarness creates a new test Harness, initialized with n servers connected to each other.
func (*SqliteHarness) CheckNoLeader ¶
func (h *SqliteHarness) CheckNoLeader()
CheckNoLeader checks that no connected server considers itself the leader.
func (*SqliteHarness) CheckSingleLeader ¶
func (h *SqliteHarness) CheckSingleLeader() (int, int)
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 (*SqliteHarness) CrashPeer ¶
func (h *SqliteHarness) CrashPeer(id int)
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 (*SqliteHarness) DisconnectPeer ¶
func (h *SqliteHarness) DisconnectPeer(id int)
DisconnectPeer disconnects a server from all other servers in the cluster.
func (*SqliteHarness) ReconnectPeer ¶
func (h *SqliteHarness) ReconnectPeer(id int)
ReconnectPeer connects a server to all other servers in the cluster.
func (*SqliteHarness) Shutdown ¶
func (h *SqliteHarness) Shutdown()
Shutdown shuts down all the servers in the harness and waits for them to stop running.
func (*SqliteHarness) SubmitToServer ¶
func (h *SqliteHarness) SubmitToServer(serverId int, cmd interface{}) bool