Skip to content
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

fix(raft): Only leader should check the quorum #6323

Merged
merged 2 commits into from
Sep 9, 2020
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 19 additions & 12 deletions dgraph/cmd/zero/raft.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,22 +51,25 @@ type node struct {
lastQuorum time.Time
}

func (n *node) AmLeader() bool {
func (n *node) amLeader() bool {
if n.Raft() == nil {
return false
}
r := n.Raft()
if r.Status().Lead != r.Status().ID {
return false
}
return r.Status().Lead == r.Status().ID
}

// This node must be the leader, but must also be an active member of the cluster, and not
// hidden behind a partition. Basically, if this node was the leader and goes behind a
// partition, it would still think that it is indeed the leader for the duration mentioned
// below.
n.mu.RLock()
defer n.mu.RUnlock()
return time.Since(n.lastQuorum) <= 5*time.Second
func (n *node) AmLeader() bool {
// Return false if the node is not the leader. Otherwise, check the lastQuorum as well.
return n.amLeader() && func() bool {
// This node must be the leader, but must also be an active member of
// the cluster, and not hidden behind a partition. Basically, if this
// node was the leader and goes behind a partition, it would still
// think that it is indeed the leader for the duration mentioned below.
n.mu.RLock()
defer n.mu.RUnlock()
return time.Since(n.lastQuorum) <= 5*time.Second
}()
}

func (n *node) uniqueKey() string {
Expand Down Expand Up @@ -630,7 +633,11 @@ func (n *node) checkQuorum(closer *y.Closer) {
for {
select {
case <-ticker.C:
quorum()
// Only the leader needs to check for the quorum. The quorum is
// used by a leader to identify if it is behind a network partition.
if n.amLeader() {
quorum()
}
case <-closer.HasBeenClosed():
return
}
Expand Down