Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
djq2
ECE 428 - Distributed Systems
Commits
25393c3f
Commit
25393c3f
authored
Mar 25, 2022
by
djq2
Browse files
Implementing structs and heartbeats
parent
9e261d40
Changes
1
Hide whitespace changes
Inline
Side-by-side
mp2/src/raft/raft.go
View file @
25393c3f
...
...
@@ -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
}
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment