Skip to content
Snippets Groups Projects
Commit 25393c3f authored by djq2's avatar djq2
Browse files

Implementing structs and heartbeats

parent 9e261d40
No related branches found
No related tags found
No related merge requests found
......@@ -20,23 +20,27 @@ package raft
import "sync"
import "sync/atomic"
import "../labrpc"
import "rand"
import "time"
//
// as each Raft peer becomes aware that successive log entries are
// committed, the peer should send an ApplyMsg to the service (or
// tester) on the same server, via the applyCh passed to Make(). set
// CommandValid to true to indicate that the ApplyMsg contains a newly
// committed log entry.
//
type ApplyMsg struct {
CommandValid bool
Command interface{}
CommandIndex int
}
//
// Log entry
type Entry struct{
Command interface{}
Term int
}
// A Go object implementing a single Raft peer.
//
type Raft struct {
mu sync.Mutex // Lock to protect shared access to this peer's state
peers []*labrpc.ClientEnd // RPC end points of all peers
......@@ -47,45 +51,66 @@ type Raft struct {
// Look at the paper's Figure 2 for a description of what
// state a Raft server must maintain.
// You may also need to add other state, as per your implementation.
}
// return currentTerm and whether this server
// believes it is the leader.
func (rf *Raft) GetState() (int, bool) {
currentTerm int // Latest term seen by this process
votedFor interface{} // Id of candidate voted for, null if not voted
log[] Entry // List of received log entries
commitIndex int // Index of highest known committed log entry
lastApplied int // Index of highest entry applied to state machine
var term int
var isleader bool
// Your code here (2A).
return term, isleader
applyCh chan // Channel to send ApplyMsg given a successfully logged command
// For Leaders Only - Metadata on Followers
nextIndex[] int // Index of next log entry to send to server <i>
matchIndex[] int // Index of highest log entry known to be replicated on server <i>
}
//
// example RequestVote RPC arguments structure.
// field names must start with capital letters!
//
// Example RequestVote RPC arguments structure.
// Field names must start with capital letters!
type RequestVoteArgs struct {
// Your data here (2A, 2B).
Term int // Candidate's (Requestor) term
CandidateID interface{} // Id of requestor/candidate
LastLogIndex int // Index of requestor/candidate last log entry
LastLogTerm int // Term of requestor/candidate last log entry
}
type AppendEntriesArgs struct {
// Your data here (2A, 2B).
}
//
// example RequestVote RPC reply structure.
// field names must start with capital letters!
//
type RequestVoteReply struct {
// Your data here (2A).
Term int // Term to update to
VoteGranted bool // True if vote received
}
//
// example RequestVote RPC handler.
//
func (rf *Raft) RequestVote(args *RequestVoteArgs, reply *RequestVoteReply) {
type AppendEntriesReply struct {
// Your data here (2A).
}
// Example RequestVote RPC handler.
func (rf *Raft) RequestVote(args *AppendEntriesArgs, reply *AppendEntriesReply) {
// Your code here (2A, 2B).
// Read the fields in "args",
// and accordingly assign the values for fields in "reply".
}
// Append Entry RPC Handler
func (rf *Raft) HandleAppendEntries(args *AppendEntriesArgs, reply *AppendEntriesReply) {
}
//
// example code to send a RequestVote RPC to a server.
// server is the index of the target server in rf.peers[].
......@@ -115,13 +140,51 @@ func (rf *Raft) RequestVote(args *RequestVoteArgs, reply *RequestVoteReply) {
// that the caller passes the address of the reply struct with &, not
// the struct itself.
//
// Request Vote RPC
func (rf *Raft) sendRequestVote(server int, args *RequestVoteArgs, reply *RequestVoteReply) bool {
ok := rf.peers[server].Call("Raft.RequestVote", args, reply)
return ok
}
// Send Append Entry RPC
func (rf *Raft) sendAppendEntries(server int, args *RequestVoteArgs, reply *RequestVoteReply) bool {
ok := rf.peers[server].Call("Raft.AppendEntries", args, reply)
return ok
}
// Follower Protocol
func (rf *Raft) Follower() {
// Start listening
for {
// Handle timeout or RPC
select {
// RPC received
case received := <-rf.peers[me].ch
if received.svcMeth == "Raft.AppendEntries" {
rf.HandleAppendEntries()
}
else if received.svcMeth == "Raft.RequestVote" {
}
// Timeout
case <-time.After( (350 + (rand.Int() % 150)) * time.Millisecond)
}
}
}
// return currentTerm and whether this server believes it is the leader.
func (rf *Raft) GetState() (int, bool) {
var term int
var isleader bool
// Your code here (2A).
return term, isleader
}
//
// the service using Raft (e.g. a k/v server) wants to start
// agreement on the next command to be appended to Raft's log. if this
// server isn't the leader, returns false. otherwise start the
......@@ -134,7 +197,6 @@ func (rf *Raft) sendRequestVote(server int, args *RequestVoteArgs, reply *Reques
// if it's ever committed. the second return value is the current
// term. the third return value is true if this server believes it is
// the leader.
//
func (rf *Raft) Start(command interface{}) (int, int, bool) {
index := -1
term := -1
......@@ -183,6 +245,10 @@ func Make(peers []*labrpc.ClientEnd, me int,
rf.me = me
// Your initialization code here (2A, 2B).
rf.applyCh = applyCh
// Instantiate node as a follower
go Follower()
return rf
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment