-
Notifications
You must be signed in to change notification settings - Fork 3.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor raft state handling #1615
Changes from all commits
f6ceb9b
be22933
232b4cf
88ef994
ec1e2e3
345382a
02764a8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,11 +12,11 @@ import ( | |
// Handler represents an HTTP endpoint for Raft to communicate over. | ||
type Handler struct { | ||
Log interface { | ||
AddPeer(u *url.URL) (uint64, *Config, error) | ||
AddPeer(u *url.URL) (id uint64, leaderID uint64, config *Config, err error) | ||
RemovePeer(id uint64) error | ||
Heartbeat(term, commitIndex, leaderID uint64) (currentIndex, currentTerm uint64, err error) | ||
Heartbeat(term, commitIndex, leaderID uint64) (currentIndex uint64, err error) | ||
WriteEntriesTo(w io.Writer, id, term, index uint64) error | ||
RequestVote(term, candidateID, lastLogIndex, lastLogTerm uint64) (uint64, error) | ||
RequestVote(term, candidateID, lastLogIndex, lastLogTerm uint64) error | ||
} | ||
} | ||
|
||
|
@@ -60,7 +60,7 @@ func (h *Handler) serveJoin(w http.ResponseWriter, r *http.Request) { | |
} | ||
|
||
// Add peer to the log. | ||
id, config, err := h.Log.AddPeer(u) | ||
id, leaderID, config, err := h.Log.AddPeer(u) | ||
if err != nil { | ||
w.Header().Set("X-Raft-Error", err.Error()) | ||
w.WriteHeader(http.StatusInternalServerError) | ||
|
@@ -69,6 +69,7 @@ func (h *Handler) serveJoin(w http.ResponseWriter, r *http.Request) { | |
|
||
// Return member's id in the cluster. | ||
w.Header().Set("X-Raft-ID", strconv.FormatUint(id, 10)) | ||
w.Header().Set("X-Raft-Leader-ID", strconv.FormatUint(leaderID, 10)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this a nice-to-do, or an integral part of this change's improvements? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It was a simple change and it cleans up the trace log since it doesn't have to keep trying to reconnect while waiting for a heartbeat. |
||
w.WriteHeader(http.StatusOK) | ||
|
||
// Write config to the body. | ||
|
@@ -120,11 +121,10 @@ func (h *Handler) serveHeartbeat(w http.ResponseWriter, r *http.Request) { | |
} | ||
|
||
// Execute heartbeat on the log. | ||
currentIndex, currentTerm, err := h.Log.Heartbeat(term, commitIndex, leaderID) | ||
currentIndex, err := h.Log.Heartbeat(term, commitIndex, leaderID) | ||
|
||
// Return current term and index. | ||
w.Header().Set("X-Raft-Index", strconv.FormatUint(currentIndex, 10)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it just not need any longer? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It makes the code a lot cleaner if we only depose a leader through heartbeats and not on every single possible RPC interaction. |
||
w.Header().Set("X-Raft-Term", strconv.FormatUint(currentTerm, 10)) | ||
|
||
// Write error, if applicable. | ||
if err != nil { | ||
|
@@ -201,14 +201,8 @@ func (h *Handler) serveRequestVote(w http.ResponseWriter, r *http.Request) { | |
return | ||
} | ||
|
||
// Execute heartbeat on the log. | ||
currentTerm, err := h.Log.RequestVote(term, candidateID, lastLogIndex, lastLogTerm) | ||
|
||
// Return current term and index. | ||
w.Header().Set("X-Raft-Term", strconv.FormatUint(currentTerm, 10)) | ||
|
||
// Write error, if applicable. | ||
if err != nil { | ||
if err := h.Log.RequestVote(term, candidateID, lastLogIndex, lastLogTerm); err != nil { | ||
w.Header().Set("X-Raft-Error", err.Error()) | ||
w.WriteHeader(http.StatusInternalServerError) | ||
return | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This matches the Raft paper. If all the nodes return the same timeout then they tend to get stuck in an election loop indefinitely where they can't get enough votes.