Skip to content

Commit

Permalink
Merge #141
Browse files Browse the repository at this point in the history
141: Correct lease with check quorum. r=Hoverbear a=Hoverbear

Fixes #140 .

You can see etcd also has this behavior: https://github.com/etcd-io/etcd/blob/83304cfc808cf6303d48c45a696f169fae422e68/raft/raft.go#L1010-L1037

```go
	case pb.MsgReadIndex:
		if r.quorum() > 1 {
			if r.raftLog.zeroTermOnErrCompacted(r.raftLog.term(r.raftLog.committed)) != r.Term {
				// Reject read only request when this leader has not committed any log entry at its term.
				return nil
			}

			// thinking: use an interally defined context instead of the user given context.
			// We can express this in terms of the term and index instead of a user-supplied value.
			// This would allow multiple reads to piggyback on the same message.
			switch r.readOnly.option {
			case ReadOnlySafe:
				r.readOnly.addRequest(r.raftLog.committed, m)
				r.bcastHeartbeatWithCtx(m.Entries[0].Data)
			case ReadOnlyLeaseBased:
				ri := r.raftLog.committed
				if m.From == None || m.From == r.id { // from local member
					r.readStates = append(r.readStates, ReadState{Index: r.raftLog.committed, RequestCtx: m.Entries[0].Data})
				} else {
					r.send(pb.Message{To: m.From, Type: pb.MsgReadIndexResp, Index: ri, Entries: m.Entries})
				}
			}
		} else {
			r.readStates = append(r.readStates, ReadState{Index: r.raftLog.committed, RequestCtx: m.Entries[0].Data})
		}

		return nil
}
```

Co-authored-by: Hoverbear <operator@hoverbear.org>
Co-authored-by: A. Hobden <operator@hoverbear.org>
  • Loading branch information
bors[bot] and Hoverbear committed Nov 13, 2018
2 parents 3799cfa + 0bf51e4 commit d8e81dc
Show file tree
Hide file tree
Showing 2 changed files with 3 additions and 6 deletions.
7 changes: 2 additions & 5 deletions src/raft.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1427,14 +1427,11 @@ impl<T: Storage> Raft<T> {
self.bcast_heartbeat_with_ctx(Some(ctx));
}
ReadOnlyOption::LeaseBased => {
let mut read_index = INVALID_INDEX;
if self.check_quorum {
read_index = self.raft_log.committed
}
let mut read_index = self.raft_log.committed;
if m.get_from() == INVALID_ID || m.get_from() == self.id {
// from local member
let rs = ReadState {
index: self.raft_log.committed,
index: read_index,
request_ctx: m.take_entries()[0].take_data(),
};
self.read_states.push(rs);
Expand Down
2 changes: 1 addition & 1 deletion tests/integration_cases/test_raft.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2295,7 +2295,7 @@ fn test_read_only_option_lease_without_check_quorum() {
let read_states = &nt.peers[&2].read_states;
assert!(!read_states.is_empty());
let rs = &read_states[0];
assert_eq!(rs.index, INVALID_ID);
assert_eq!(rs.index, 1);
let vec_ctx = ctx.as_bytes().to_vec();
assert_eq!(rs.request_ctx, vec_ctx);
}
Expand Down

0 comments on commit d8e81dc

Please sign in to comment.