/** * Work through the chosen messages sending what we have left and stopping once we get to an * unfilled slot or the end of the array. */ private void onChosen(PaxosMessage proposal) { chosen.set(proposal.getInstanceNum(), (ChatMessage) proposal.getValue()); if (proposal.getInstanceNum() >= nextInstance) nextInstance = proposal.getInstanceNum() + 1; while (lastSent + 1 < chosen.size()) { ChatMessage toSend = chosen.get(lastSent + 1); if (toSend != null) { if (nodeIsLeader()) sendToClients(toSend); lastSent++; } else { break; // There is still a missing slot. } } }
@Override public void handlePropose(PaxosMessage proposal) { if (preparedFor > proposal.getProposeNum()) return; ensureSize(accepted, proposal.getInstanceNum() + 1); ensureSize(chosen, proposal.getInstanceNum() + 1); accepted.set(proposal.getInstanceNum(), (ChatMessage) proposal.getValue()); // Send accept to all /* sendAllMessage(new DefaultPaxosMessage(proposal.getInstanceNum(), proposal.getProposeNum(), id, PaxosMessageType.ACCEPTED, proposal.getValue())); */ // Silently accept proposals }
@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); } }