Esempio n. 1
0
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);
}
Esempio n. 2
0
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();
}