diff --git a/config.go b/config.go new file mode 100644 index 000000000..8b68f07b6 --- /dev/null +++ b/config.go @@ -0,0 +1,18 @@ +package raft + +import ( + "time" +) + +// Config provides any necessary configuraiton to +// the Raft server +type Config struct { + // Time without a leader before we attempt an election + ElectionTimeout time.Duration +} + +func DefaultConfig() *Config { + return &Config{ + ElectionTimeout: 150 * time.Millisecond, + } +} diff --git a/leader.go b/leader.go new file mode 100644 index 000000000..92460ee76 --- /dev/null +++ b/leader.go @@ -0,0 +1,15 @@ +package raft + +// LeaderState is used to track the additional state +// needed as a leader +type LeaderState struct { + followers map[string]*FollowerState +} + +type FollowerState struct { + // This is the next index to send + nextIndex uint64 + + // This is the last known replicated index + replicatedIndex uint64 +} diff --git a/log.go b/log.go new file mode 100644 index 000000000..b1bf9d3ff --- /dev/null +++ b/log.go @@ -0,0 +1,25 @@ +package raft + +// Log entries are replicated to all members of the Raft cluster +// and form the heart of the replicated state machine. +type Log struct { + Index uint64 + Term uint64 + Data []byte +} + +// LogStore is used to provide an interface for storing +// and retrieving logs in a durable fashion +type LogStore interface { + // Returns the last index written. 0 for no entries. + LastIndex() (uint64, error) + + // Gets a log entry at a given index + GetLog(index uint64, log *Log) error + + // Stores a log entry + StoreLog(log *Log) error + + // Deletes a range of log entries. The range is inclusive. + DeleteRange(min, max uint64) error +} diff --git a/raft.go b/raft.go new file mode 100644 index 000000000..3fd1ef067 --- /dev/null +++ b/raft.go @@ -0,0 +1,32 @@ +package raft + +type RaftState uint8 + +const ( + Follower RaftState = iota + Candidate + Leader +) + +type Raft struct { + // Configuration + conf *Config + + // Current state + state RaftState + + // stable is a StableStore implementation for durable state + stable StableStore + + // logs is a LogStore implementation to keep our logs + logs LogStore + + // Highest commited log entry + commitIndex uint64 + + // Last applied log to the FSM + lastApplied uint64 + + // If we are the leader, we have extra state + leader *LeaderState +} diff --git a/stable.go b/stable.go new file mode 100644 index 000000000..80cad77ca --- /dev/null +++ b/stable.go @@ -0,0 +1,21 @@ +package raft + +// StableStore is used to provide stable storage +// of key configurations to ensure safety. +type StableStore interface { + // Returns the current term + CurrentTerm() (uint64, error) + + // Returns the candidate we voted for this term + VotedFor() (string, error) + + // Sets the current term. Clears the current vote. + SetCurrentTerm(uint64) error + + // Sets a candidate vote for the current term + SetVote(string) error + + // Returns our candidate ID. This should be unique + // and constant across runs + CandidateID() (string, error) +}