void PaxosProposer::OnProposeResponse(PaxosMessage& imsg) { PaxosMessage omsg; Log_Trace("msg.nodeID = %u", imsg.nodeID); if (!state.proposing || imsg.proposalID != state.proposalID) return; if (imsg.type == PAXOS_PROPOSE_REJECTED) { Log_Debug("Propose rejected"); vote->RegisterRejected(imsg.nodeID); } else vote->RegisterAccepted(imsg.nodeID); // see if we have enough positive replies to advance if (vote->IsAccepted()) { // a majority have accepted our proposal, we have consensus StopProposing(); omsg.LearnProposal(context->GetPaxosID(), MY_NODEID, state.proposalID); BroadcastMessage(omsg); } else if (vote->IsComplete()) StartPreparing(); }
void PaxosProposer::OnProposeResponse(PaxosMessage& imsg) { PaxosMessage omsg; Log_Trace("msg.nodeID = %u", imsg.nodeID); if (!state.proposing || imsg.proposalID != state.proposalID) return; if (imsg.type == PAXOS_PROPOSE_REJECTED) { Log_Debug("Propose rejected, quorumID: %U", context->GetQuorumID()); vote->RegisterRejected(imsg.nodeID); } else vote->RegisterAccepted(imsg.nodeID); if (vote->IsRejected()) { StopProposing(); EventLoop::Add(&restartTimeout); } else if (vote->IsAccepted()) { // a majority have accepted our proposal, we have consensus StopProposing(); omsg.LearnProposal(context->GetPaxosID(), MY_NODEID, state.proposalID); BroadcastMessage(omsg); state.learnSent = true; } }
void ReplicatedLog::OnMessage(PaxosMessage& imsg) { Log_Trace(); bool processed; processed = false; if (imsg.type == PAXOS_PREPARE_REQUEST) processed = OnPrepareRequest(imsg); else if (imsg.IsPrepareResponse()) processed = OnPrepareResponse(imsg); else if (imsg.type == PAXOS_PROPOSE_REQUEST) processed = OnProposeRequest(imsg); else if (imsg.IsProposeResponse()) processed = OnProposeResponse(imsg); else if (imsg.IsLearn()) processed = OnLearnChosen(imsg); else if (imsg.type == PAXOS_REQUEST_CHOSEN) processed = OnRequestChosen(imsg); else if (imsg.type == PAXOS_START_CATCHUP) processed = OnStartCatchup(imsg); else ASSERT_FAIL(); if (processed) context->OnMessageProcessed(); }
void ReplicatedLog::OnRequestChosen(PaxosMessage& imsg) { Buffer value; PaxosMessage omsg; #ifdef RLOG_DEBUG_MESSAGES Log_Debug("ReplicatedLog::OnRequestChosen, imsg.paxosID = %U, mine = %U", imsg.paxosID, GetPaxosID()); #endif if (imsg.paxosID >= GetPaxosID()) return; // the node is lagging and needs to catch-up context->GetDatabase()->GetAcceptedValue(imsg.paxosID, value); if (value.GetLength() > 0) { Log_Trace("Sending paxosID %d to node %d", imsg.paxosID, imsg.nodeID); omsg.LearnValue(imsg.paxosID, MY_NODEID, 0, value); } else { Log_Trace("Node requested a paxosID I no longer have"); omsg.StartCatchup(paxosID, MY_NODEID); } context->GetTransport()->SendMessage(imsg.nodeID, omsg); }
void PaxosProposer::OnMessage(PaxosMessage& imsg) { if (imsg.IsPrepareResponse()) OnPrepareResponse(imsg); else if (imsg.IsProposeResponse()) OnProposeResponse(imsg); else ASSERT_FAIL(); }
void ReplicatedLog::RequestChosen(uint64_t nodeID) { PaxosMessage omsg; if (context->IsLeaseOwner() || EventLoop::Now() - lastRequestChosenTime < REQUEST_CHOSEN_TIMEOUT) return; lastRequestChosenTime = EventLoop::Now(); omsg.RequestChosen(GetPaxosID(), MY_NODEID); context->GetTransport()->SendMessage(nodeID, omsg); #ifdef RLOG_DEBUG_MESSAGES Log_Debug("ReplicatedLog::RequestChosen, paxosID = %U, to = %U", GetPaxosID(), nodeID); #endif }
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::StartPreparing() { PaxosMessage omsg; Log_Trace(); StopProposing(); NewVote(); state.preparing = true; state.numProposals++; state.proposalID = REPLICATION_CONFIG->NextProposalID(MAX(state.proposalID, state.highestPromisedProposalID)); state.highestReceivedProposalID = 0; omsg.PrepareRequest(context->GetPaxosID(), MY_NODEID, state.proposalID); BroadcastMessage(omsg); EventLoop::Reset(&prepareTimeout); }
void ReplicatedLog::OnRequest(PaxosMessage& imsg) { Buffer value; PaxosMessage omsg; Log_Trace(); if (imsg.paxosID < GetPaxosID()) { context->GetDatabase()->GetAcceptedValue(imsg.paxosID, value); if (value.GetLength() == 0) return; omsg.LearnValue(imsg.paxosID, MY_NODEID, 0, value); context->GetTransport()->SendMessage(imsg.nodeID, omsg); } else if (GetPaxosID() < imsg.paxosID) { // I am lagging and need to catch-up RequestChosen(imsg.nodeID); } }
void ReplicatedLog::OnMessage(PaxosMessage& imsg) { Log_Trace(); if (imsg.type == PAXOS_PREPARE_REQUEST) OnPrepareRequest(imsg); else if (imsg.IsPrepareResponse()) OnPrepareResponse(imsg); else if (imsg.type == PAXOS_PROPOSE_REQUEST) OnProposeRequest(imsg); else if (imsg.IsProposeResponse()) OnProposeResponse(imsg); else if (imsg.IsLearn()) OnLearnChosen(imsg); else if (imsg.type == PAXOS_REQUEST_CHOSEN) OnRequestChosen(imsg); else if (imsg.type == PAXOS_START_CATCHUP) OnStartCatchup(imsg); else ASSERT_FAIL(); }
void ConfigQuorumContext::OnPaxosMessage(ReadBuffer buffer) { PaxosMessage msg; if (!isReplicationActive) return; msg.Read(buffer); if (msg.IsPaxosRequest() || msg.IsPaxosResponse() || msg.IsLearn()) { if (!quorum.IsMember(msg.nodeID)) { Log_Message("Dropping paxos msg from %U because that node is not a quourm member", msg.nodeID); OnMessageProcessed(); return; } } RegisterPaxosID(msg.paxosID); replicatedLog.RegisterPaxosID(msg.paxosID, msg.nodeID); replicatedLog.OnMessage(msg); }