/** * In the case there is a leader elected, and a quorum supporting * this leader, we have to check if the leader has voted and acked * that it is leading. We need this check to avoid that peers keep * electing over and over a peer that has crashed and it is no * longer leading. * * @param votes set of votes * @param leader leader id * @param electionEpoch epoch id */ protected boolean checkLeader( Map<Long, Vote> votes, long leader, long electionEpoch){ boolean predicate = true; /* * If everyone else thinks I'm the leader, I must be the leader. * The other two checks are just for the case in which I'm not the * leader. If I'm not the leader and I haven't received a message * from leader stating that it is leading, then predicate is false. */ if(leader != self.getId()){ if(votes.get(leader) == null) predicate = false; else if(votes.get(leader).getState() != ServerState.LEADING) predicate = false; } else if(logicalclock.get() != electionEpoch) { predicate = false; } return predicate; }
else if(votes.get(leader).getState() != ServerState.LEADING) predicate = false; } else if(logicalclock.get() != electionEpoch) { predicate = false;
e.setValue(new Vote(v.getId(), zxid, v.getElectionEpoch(), v.getPeerEpoch(), v.getState()));
currentVote.getElectionEpoch(), newEpoch, currentVote.getState()));
/** * Updates leader election info to avoid inconsistencies when * a new server tries to join the ensemble. * See ZOOKEEPER-1732 for more info. */ protected void updateElectionVote(long newEpoch) { Vote currentVote = getCurrentVote(); setBCVote(currentVote); if (currentVote != null) { setCurrentVote(new Vote(currentVote.getId(), currentVote.getZxid(), currentVote.getElectionEpoch(), newEpoch, currentVote.getState())); } }
@Test public void testOutofElection() { HashMap<Long,Vote> outofelection = new HashMap<Long,Vote>(); outofelection.put(1L, new Vote(0x0, 5, ZxidUtils.makeZxid(15, 0), 0xa, 0x17, ServerState.FOLLOWING)); outofelection.put(2L, new Vote(0x0, 5, ZxidUtils.makeZxid(15, 0), 0xa, 0x17, ServerState.FOLLOWING)); outofelection.put(4L, new Vote(0x1, 5, ZxidUtils.makeZxid(15, 0), 0xa, 0x18, ServerState.FOLLOWING)); Vote vote = new Vote(0x1, 5, ZxidUtils.makeZxid(15, 0), 0xa, 0x18, ServerState.LEADING); outofelection.put(5L, vote); Notification n = new Notification(); n.version = vote.getVersion(); n.leader = vote.getId(); n.zxid = vote.getZxid(); n.electionEpoch = vote.getElectionEpoch(); n.state = vote.getState(); n.peerEpoch = vote.getPeerEpoch(); n.sid = 5L; // Set the logical clock to 1 on fle instance of server 3. fle.logicalclock.set(0x1); Assert.assertTrue("Quorum check failed", fle.getVoteTracker(outofelection, new Vote(n.version, n.leader, n.zxid, n.electionEpoch, n.peerEpoch, n.state)).hasAllQuorums()); Assert.assertTrue("Leader check failed", fle.checkLeader(outofelection, n.leader, n.electionEpoch)); } }
long zxid = peer.getCurrentVote().getZxid(); long electionEpoch = peer.getCurrentVote().getElectionEpoch(); ServerState state = peer.getCurrentVote().getState(); long peerEpoch = peer.getCurrentVote().getPeerEpoch(); Vote newVote = new Vote(leaderSid, zxid+100, electionEpoch+100, peerEpoch, state);
/** * Updates leader election info to avoid inconsistencies when * a new server tries to join the ensemble. * See ZOOKEEPER-1732 for more info. */ protected void updateElectionVote(long newEpoch) { Vote currentVote = getCurrentVote(); setBCVote(currentVote); if (currentVote != null) { setCurrentVote(new Vote(currentVote.getId(), currentVote.getZxid(), currentVote.getElectionEpoch(), newEpoch, currentVote.getState())); } }