+
+ // Check whether we should update the term. In case of half-connected nodes, we want to ignore RequestVote
+ // messages, as the candidate is not able to receive our response.
+ protected boolean shouldUpdateTerm(final RaftRPC rpc) {
+ if (!(rpc instanceof RequestVote)) {
+ return true;
+ }
+
+ final RequestVote requestVote = (RequestVote) rpc;
+ log.debug("{}: Found higher term in RequestVote rpc, verifying whether it's safe to update term.", logName());
+ final Optional<Cluster> maybeCluster = context.getCluster();
+ if (!maybeCluster.isPresent()) {
+ return true;
+ }
+
+ final Cluster cluster = maybeCluster.get();
+
+ final Set<Member> unreachable = cluster.state().getUnreachable();
+ log.debug("{}: Cluster state: {}", logName(), unreachable);
+
+ for (Member member : unreachable) {
+ for (String role : member.getRoles()) {
+ if (requestVote.getCandidateId().startsWith(role)) {
+ log.debug("{}: Unreachable member: {}, matches candidateId in: {}, not updating term", logName(),
+ member, requestVote);
+ return false;
+ }
+ }
+ }
+
+ log.debug("{}: Candidate in requestVote:{} with higher term appears reachable, updating term.", logName(),
+ requestVote);
+ return true;
+ }