@Override public void handleAccepted(PaxosMessage proposal) { ensureSize(chosen, proposal.getInstanceNum() + 1); // Prevent NPE if (chosen.get(proposal.getInstanceNum()) != null) return; // Something has already been chosen so I dont care anymore. List<PaxosMessage> acceptedVotes = proposalAcceptedVotes.get(proposal.getInstanceNum()); if (acceptedVotes == null) { acceptedVotes = new ArrayList<PaxosMessage>(); acceptedVotes.add(proposal); proposalAcceptedVotes.put(proposal.getInstanceNum(), acceptedVotes); } else { for (PaxosMessage acceptedVote : acceptedVotes) { if (proposal.getProposerId() == acceptedVote.getProposerId()) return; // This person is reaffirming their acceptance of this instances proposal. } acceptedVotes.add(proposal); proposalAcceptedVotes.put(proposal.getInstanceNum(), acceptedVotes); } // handle being chosen if (proposalAcceptedVotes.get(proposal.getInstanceNum()).size() >= serverSet.getQuorumSize()) { onChosen(proposal); } }
@Override public void handlePrepareResponse(PaxosMessage response) { if (!prepareResponseFrom.contains(response.getProposerId())) prepareResponseFrom.add( response.getProposerId()); // This is a new server accepted our prepare request. List<ChatMessage> remoteAccepted = (List<ChatMessage>) response.getValue(); for (int i = 0; i < remoteAccepted.size(); i++) { if (chosen.size() > i && chosen.get(i) != null) continue; if (remoteAccepted.get(i) != null) { propose( new DefaultPaxosMessage( i, nextPropose, id, PaxosMessageType.PROPOSE, remoteAccepted.get(i))); if (i > nextInstance) nextInstance = i; } } }
/** * Adds nulls to the end of list until it is at least size. * * @param list * @param size */ private void ensureSize(List list, int size) { while (list.size() < size) { list.add(null); } }