mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
raft: remove quorum() dependency from readOnly
This now delegates the quorum computation to r.prs, which will allow it to generalize in a straightforward way when etcd-io/etcd#7625 is addressed.
This commit is contained in:
parent
57a1b39fcd
commit
02b0d80234
@ -320,6 +320,10 @@ func (p *prs) quorum() int {
|
||||
return len(p.nodes)/2 + 1
|
||||
}
|
||||
|
||||
func (p *prs) hasQuorum(m map[uint64]struct{}) bool {
|
||||
return len(m) >= p.quorum()
|
||||
}
|
||||
|
||||
// committed returns the largest log index known to be committed based on what
|
||||
// the voting members of the group have acknowledged.
|
||||
func (p *prs) committed() uint64 {
|
||||
|
@ -1000,6 +1000,8 @@ func stepLeader(r *raft, m pb.Message) error {
|
||||
switch r.readOnly.option {
|
||||
case ReadOnlySafe:
|
||||
r.readOnly.addRequest(r.raftLog.committed, m)
|
||||
// The local node automatically acks the request.
|
||||
r.readOnly.recvAck(r.id, m.Entries[0].Data)
|
||||
r.bcastHeartbeatWithCtx(m.Entries[0].Data)
|
||||
case ReadOnlyLeaseBased:
|
||||
ri := r.raftLog.committed
|
||||
@ -1097,8 +1099,7 @@ func stepLeader(r *raft, m pb.Message) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
ackCount := r.readOnly.recvAck(m)
|
||||
if ackCount < r.prs.quorum() {
|
||||
if !r.prs.hasQuorum(r.readOnly.recvAck(m.From, m.Context)) {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -50,26 +50,25 @@ func newReadOnly(option ReadOnlyOption) *readOnly {
|
||||
// the read only request.
|
||||
// `m` is the original read only request message from the local or remote node.
|
||||
func (ro *readOnly) addRequest(index uint64, m pb.Message) {
|
||||
ctx := string(m.Entries[0].Data)
|
||||
if _, ok := ro.pendingReadIndex[ctx]; ok {
|
||||
s := string(m.Entries[0].Data)
|
||||
if _, ok := ro.pendingReadIndex[s]; ok {
|
||||
return
|
||||
}
|
||||
ro.pendingReadIndex[ctx] = &readIndexStatus{index: index, req: m, acks: make(map[uint64]struct{})}
|
||||
ro.readIndexQueue = append(ro.readIndexQueue, ctx)
|
||||
ro.pendingReadIndex[s] = &readIndexStatus{index: index, req: m, acks: make(map[uint64]struct{})}
|
||||
ro.readIndexQueue = append(ro.readIndexQueue, s)
|
||||
}
|
||||
|
||||
// recvAck notifies the readonly struct that the raft state machine received
|
||||
// an acknowledgment of the heartbeat that attached with the read only request
|
||||
// context.
|
||||
func (ro *readOnly) recvAck(m pb.Message) int {
|
||||
rs, ok := ro.pendingReadIndex[string(m.Context)]
|
||||
func (ro *readOnly) recvAck(id uint64, context []byte) map[uint64]struct{} {
|
||||
rs, ok := ro.pendingReadIndex[string(context)]
|
||||
if !ok {
|
||||
return 0
|
||||
return nil
|
||||
}
|
||||
|
||||
rs.acks[m.From] = struct{}{}
|
||||
// add one to include an ack from local node
|
||||
return len(rs.acks) + 1
|
||||
rs.acks[id] = struct{}{}
|
||||
return rs.acks
|
||||
}
|
||||
|
||||
// advance advances the read only request queue kept by the readonly struct.
|
||||
|
Loading…
x
Reference in New Issue
Block a user