in src/main/java/org/apache/sling/discovery/impl/cluster/voting/VotingHandler.java [231:355]
public synchronized Map<VotingView,VotingDetail> analyzeVotings(final ResourceResolver resourceResolver) throws PersistenceException {
if (!activated) {
logger.info("analyzeVotings: VotingHandler not yet initialized, can't vote.");
return null;
}
Map<VotingView,VotingDetail> result = new HashMap<VotingView,VotingDetail>();
// SLING-3406: refreshing resourceResolver/session here to get the latest state from the repository
logger.debug("analyzeVotings: start. slingId: {}", slingId);
resourceResolver.refresh();
VotingView winningVote = VotingHelper.getWinningVoting(
resourceResolver, config);
if (winningVote != null) {
if (winningVote.isInitiatedBy(slingId)) {
logger.info("analyzeVotings: my voting was winning. I'll mark it as established then! "
+ winningVote);
try{
promote(resourceResolver, winningVote.getResource());
} catch (RuntimeException re) {
logger.error("analyzeVotings: RuntimeException during promotion: "+re, re);
throw re;
} catch (Error er) {
logger.error("analyzeVotings: Error during promotion: "+er, er);
throw er;
}
// SLING-3406: committing resourceResolver/session here, while we're in the synchronized
resourceResolver.commit();
// for test verification
result.put(winningVote, VotingDetail.PROMOTED);
return result;
} else {
logger.info("analyzeVotings: there is a winning vote. No need to vote any further. Expecting it to get promoted to established: "
+ winningVote);
result.put(winningVote, VotingDetail.WINNING);
return result;
}
}
List<VotingView> ongoingVotings = VotingHelper.listVotings(resourceResolver, config);
if (ongoingVotings == null || ongoingVotings.size() == 0) {
logger.debug("analyzeVotings: no ongoing votings at the moment. done.");
return result;
}
Collections.sort(ongoingVotings, VOTING_COMPARATOR);
VotingView yesVote = null;
for (VotingView voting : ongoingVotings) {
Boolean myVote = voting.getVote(slingId);
boolean votedNo = myVote != null && !myVote;
boolean votedYes = myVote != null && myVote;
if (voting.isTimedoutVoting(config)) {
// if a voting has timed out, delete it
logger.info("analyzeVotings: deleting a timed out voting: "+voting);
voting.remove(false);
result.put(voting, VotingDetail.TIMEDOUT);
continue;
}
if (voting.hasNoVotes()) {
if (!votedNo) {
logger.info("analyzeVotings: vote already has no votes, so I shall also vote no: "+voting);
voting.vote(slingId, false, null);
result.put(voting, VotingDetail.VOTED_NO);
} else {
// else ignore silently
result.put(voting, VotingDetail.UNCHANGED);
}
continue;
}
if (!voting.isOngoingVoting(config)) {
logger.debug("analyzeVotings: vote is not ongoing (ignoring): "+voting);
continue;
}
String liveComparison;
try {
liveComparison = voting.matchesLiveView(config);
} catch (Exception e) {
logger.error("analyzeVotings: could not compare voting with live view: "+e, e);
continue;
}
if (liveComparison != null) {
if (!votedNo) {
logger.info("analyzeVotings: vote doesnt match my live view, voting no. "
+ "comparison result: "+liveComparison+", vote: "+voting);
voting.vote(slingId, false, null);
result.put(voting, VotingDetail.VOTED_NO);
} else {
result.put(voting, VotingDetail.UNCHANGED);
}
continue;
}
if (yesVote != null) {
// as soon as I found the one I should vote yes for,
// vote no for the rest
if (!votedNo) {
logger.info("analyzeVotings: already voted yes, so voting no for: "+voting);
voting.vote(slingId, false, null);
result.put(voting, VotingDetail.VOTED_NO);
} else {
// else ignore silently
result.put(voting, VotingDetail.UNCHANGED);
}
continue;
}
if (!votedYes) {
logger.info("analyzeVotings: not timed out, no no-votes, matches live, still ongoing, "
+ "I have not yet voted yes, so noting candidate for yes as: "+voting);
}
yesVote = voting;
}
if (yesVote != null) {
Boolean myVote = yesVote.getVote(slingId);
boolean votedYes = myVote != null && myVote;
if (!votedYes) {
logger.info("analyzeVotings: declaring my personal winner: "+yesVote+" (myVote==null: "+(myVote==null)+")");
yesVote.vote(slingId, true, leaderElectionId);
result.put(yesVote, VotingDetail.VOTED_YES);
} else {
// else don't double vote / log
result.put(yesVote, VotingDetail.UNCHANGED);
}
}
resourceResolver.commit();
logger.debug("analyzeVotings: result: my yes vote was for: " + yesVote);
return result;
}