Skip to content

Commit

Permalink
Merge branch 'master' of github.com:hashicorp/raft
Browse files Browse the repository at this point in the history
* 'master' of github.com:hashicorp/raft:
  more efficient append bytes (hashicorp#399)
  Ignore non-voters in leadership transfer (hashicorp#398)
  • Loading branch information
yuyang committed Apr 19, 2020
2 parents 7eb03e7 + d31be9a commit 4e2c35a
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 6 deletions.
6 changes: 3 additions & 3 deletions inmem_snapshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,9 @@ func (m *InmemSnapshotStore) Open(id string) (*SnapshotMeta, io.ReadCloser, erro

// Write appends the given bytes to the snapshot contents
func (s *InmemSnapshotSink) Write(p []byte) (n int, err error) {
written, err := io.Copy(s.contents, bytes.NewReader(p))
s.meta.Size += written
return int(written), err
written, err := s.contents.Write(p)
s.meta.Size += int64(written)
return written, err
}

// Close updates the Size and is otherwise a no-op
Expand Down
6 changes: 3 additions & 3 deletions raft.go
Original file line number Diff line number Diff line change
Expand Up @@ -1752,13 +1752,13 @@ func (r *Raft) lookupServer(id ServerID) *Server {
return nil
}

// pickServer returns the follower that is most up to date. Because it accesses
// leaderstate, it should only be called from the leaderloop.
// pickServer returns the follower that is most up to date and participating in quorum.
// Because it accesses leaderstate, it should only be called from the leaderloop.
func (r *Raft) pickServer() *Server {
var pick *Server
var current uint64
for _, server := range r.configurations.latest.Servers {
if server.ID == r.localID {
if server.ID == r.localID || server.Suffrage != Voter {
continue
}
state, ok := r.leaderState.replState[server.ID]
Expand Down
23 changes: 23 additions & 0 deletions raft_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2094,6 +2094,29 @@ func TestRaft_LeadershipTransferLeaderReplicationTimeout(t *testing.T) {
}
}

func TestRaft_LeadershipTransferIgnoresNonvoters(t *testing.T) {
c := MakeCluster(2, t, nil)
defer c.Close()

follower := c.Followers()[0]

demoteFuture := c.Leader().DemoteVoter(follower.localID, 0, 0)
if demoteFuture.Error() != nil {
t.Fatalf("demote voter err'd: %v", demoteFuture.Error())
}

future := c.Leader().LeadershipTransfer()
if future.Error() == nil {
t.Fatal("leadership transfer should err")
}

expected := "cannot find peer"
actual := future.Error().Error()
if !strings.Contains(actual, expected) {
t.Errorf("leadership transfer should err with: %s", expected)
}
}

func TestRaft_LeadershipTransferStopRightAway(t *testing.T) {
r := Raft{leaderState: leaderState{}}
r.setupLeaderState()
Expand Down

0 comments on commit 4e2c35a

Please sign in to comment.