Repository: kudu Updated Branches: refs/heads/master 29e795d58 -> cc4e3957b
[consensus] fix on RequestForPeer clean-up The consensus queue can switch to the non-leader mode when exiting from the RequestForPeer() method scope, so it's necessary to check for that condition in the scoped clean-up object before updating information on the peer's health. The issue was found while running the raft_consensus_stress-itest for the 3-2-3 re-replication scheme, so I don't think any additional test is needed to cover this change. Change-Id: I71b3b47bbf9b5011bd11534287f6ae8f760addd5 Reviewed-on: http://gerrit.cloudera.org:8080/9487 Tested-by: Kudu Jenkins Reviewed-by: Mike Percy <[email protected]> Project: http://git-wip-us.apache.org/repos/asf/kudu/repo Commit: http://git-wip-us.apache.org/repos/asf/kudu/commit/f38213d8 Tree: http://git-wip-us.apache.org/repos/asf/kudu/tree/f38213d8 Diff: http://git-wip-us.apache.org/repos/asf/kudu/diff/f38213d8 Branch: refs/heads/master Commit: f38213d8dcf233891cc1d0f18b3c68d9ad67f429 Parents: 29e795d Author: Alexey Serbin <[email protected]> Authored: Sun Mar 4 10:19:11 2018 -0800 Committer: Alexey Serbin <[email protected]> Committed: Mon Mar 5 19:03:57 2018 +0000 ---------------------------------------------------------------------- src/kudu/consensus/consensus_queue.cc | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/kudu/blob/f38213d8/src/kudu/consensus/consensus_queue.cc ---------------------------------------------------------------------- diff --git a/src/kudu/consensus/consensus_queue.cc b/src/kudu/consensus/consensus_queue.cc index 4f81b88..5b6206d 100644 --- a/src/kudu/consensus/consensus_queue.cc +++ b/src/kudu/consensus/consensus_queue.cc @@ -500,6 +500,7 @@ bool PeerMessageQueue::SafeToEvictUnlocked(const string& evict_uuid) const { void PeerMessageQueue::UpdatePeerHealthUnlocked(TrackedPeer* peer) { DCHECK(queue_lock_.is_locked()); + DCHECK_EQ(LEADER, queue_state_.mode); auto overall_health_status = PeerHealthStatus(*peer); @@ -611,7 +612,11 @@ Status PeerMessageQueue::RequestForPeer(const string& uuid, SCOPED_CLEANUP({ std::lock_guard<simple_spinlock> lock(queue_lock_); TrackedPeer* peer = FindPtrOrNull(peers_map_, uuid); - if (!peer) return; + if (PREDICT_FALSE(peer == nullptr || queue_state_.mode == NON_LEADER)) { + VLOG(1) << LogPrefixUnlocked() << "peer " << uuid + << " is no longer tracked or queue is not in leader mode"; + return; + } if (wal_catchup_progress) peer->wal_catchup_possible = true; if (wal_catchup_failure) peer->wal_catchup_possible = false; UpdatePeerHealthUnlocked(peer); @@ -843,7 +848,11 @@ void PeerMessageQueue::UpdatePeerStatus(const string& peer_uuid, const Status& status) { std::unique_lock<simple_spinlock> l(queue_lock_); TrackedPeer* peer = FindPtrOrNull(peers_map_, peer_uuid); - if (!peer) return; + if (PREDICT_FALSE(peer == nullptr || queue_state_.mode == NON_LEADER)) { + VLOG(1) << LogPrefixUnlocked() << "peer " << peer_uuid + << " is no longer tracked or queue is not in leader mode"; + return; + } peer->last_exchange_status = ps; if (ps != PeerStatus::RPC_LAYER_ERROR) {
