void PaxosProposer::StartProposing() { PaxosMessage omsg; Log_Trace(); StopPreparing(); NewVote(); state.proposing = true; ASSERT(state.proposedValue.GetLength() > 0); omsg.ProposeRequest(context->GetPaxosID(), MY_NODEID, state.proposalID, state.proposedRunID, state.proposedValue); BroadcastMessage(omsg); EventLoop::Reset(&proposeTimeout); }
void PaxosProposer::OnPrepareResponse(PaxosMessage& imsg) { Log_Trace("msg.nodeID = %u", imsg.nodeID); if (!state.preparing || imsg.proposalID != state.proposalID) return; if (imsg.type == PAXOS_PREPARE_REJECTED) vote->RegisterRejected(imsg.nodeID); else vote->RegisterAccepted(imsg.nodeID); if (imsg.type == PAXOS_PREPARE_REJECTED) { Log_Debug("Prepare rejected, quorumID: %U", context->GetQuorumID()); if (imsg.promisedProposalID > state.highestPromisedProposalID) state.highestPromisedProposalID = imsg.promisedProposalID; } else if (imsg.type == PAXOS_PREPARE_PREVIOUSLY_ACCEPTED && imsg.acceptedProposalID >= state.highestReceivedProposalID) { /* the >= could be replaced by > which would result in less copys * however this would result in complications in multi paxos * in the multi paxos steady state this branch is inactive * it only runs after leader failure * so it's ok */ state.highestReceivedProposalID = imsg.acceptedProposalID; state.proposedRunID = imsg.runID; ASSERT(imsg.value.GetLength() > 0); state.proposedValue.Write(imsg.value); } if (vote->IsRejected()) { StopPreparing(); EventLoop::Add(&restartTimeout); } else if (vote->IsAccepted()) StartProposing(); }