Skip to content

Commit 98c2891

Browse files
committed
NRG: Ensure proposal and AE response queues drain after stepdown
Signed-off-by: Neil Twigg <[email protected]>
1 parent 6c33673 commit 98c2891

File tree

2 files changed

+34
-6
lines changed

2 files changed

+34
-6
lines changed

server/raft.go

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1989,9 +1989,11 @@ func (n *raft) runAsFollower() {
19891989
n.debug("Ignoring old vote response, we have stepped down")
19901990
n.votes.popOne()
19911991
case <-n.resp.ch:
1992-
// We're receiving append entry responses from the network, probably because
1993-
// we have only just stepped down and they were already in flight. Ignore them.
1994-
n.resp.popOne()
1992+
// Ignore append entry responses received from before the state change.
1993+
n.resp.drain()
1994+
case <-n.prop.ch:
1995+
// Ignore proposals received from before the state change.
1996+
n.prop.drain()
19951997
case <-n.reqs.ch:
19961998
// We've just received a vote request from the network.
19971999
// Because of drain() it is possible that we get nil from popOne().
@@ -2966,8 +2968,11 @@ func (n *raft) runAsCandidate() {
29662968
case <-n.entry.ch:
29672969
n.processAppendEntries()
29682970
case <-n.resp.ch:
2969-
// Ignore
2970-
n.resp.popOne()
2971+
// Ignore append entry responses received from before the state change.
2972+
n.resp.drain()
2973+
case <-n.prop.ch:
2974+
// Ignore proposals received from before the state change.
2975+
n.prop.drain()
29712976
case <-n.s.quitCh:
29722977
n.shutdown(false)
29732978
return
@@ -4089,8 +4094,9 @@ func (n *raft) switchState(state RaftState) {
40894094

40904095
if pstate == Leader && state != Leader {
40914096
n.updateLeadChange(false)
4092-
// Drain the response queue.
4097+
// Drain the append entry response and proposal queues.
40934098
n.resp.drain()
4099+
n.prop.drain()
40944100
} else if state == Leader && pstate != Leader {
40954101
if len(n.pae) > 0 {
40964102
n.pae = make(map[uint64]*appendEntry)

server/raft_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,28 @@ func TestNRGSimpleElection(t *testing.T) {
295295
}
296296
}
297297

298+
func TestNRGSwitchStateClearsQueues(t *testing.T) {
299+
c := createJetStreamClusterExplicit(t, "R3S", 3)
300+
defer c.shutdown()
301+
302+
rg := c.createMemRaftGroup("TEST", 3, newStateAdder)
303+
rg.waitOnLeader()
304+
305+
sa := rg.leader().(*stateAdder)
306+
n := sa.node().(*raft)
307+
308+
for i := 0; i < 10_000; i++ {
309+
sa.proposeDelta(1)
310+
}
311+
312+
n.Lock()
313+
defer n.Unlock()
314+
315+
n.switchState(Follower)
316+
require_Equal(t, n.prop.len(), 0)
317+
require_Equal(t, n.resp.len(), 0)
318+
}
319+
298320
func TestNRGStepDownOnSameTermDoesntClearVote(t *testing.T) {
299321
c := createJetStreamClusterExplicit(t, "R3S", 3)
300322
defer c.shutdown()

0 commit comments

Comments
 (0)