Пример #1
0
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();
}
Пример #2
0
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;
    }
}
Пример #3
0
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();
}
Пример #4
0
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);
}
Пример #5
0
void PaxosProposer::OnMessage(PaxosMessage& imsg)
{
    if (imsg.IsPrepareResponse())
        OnPrepareResponse(imsg);
    else if (imsg.IsProposeResponse())
        OnProposeResponse(imsg);
    else
        ASSERT_FAIL();
}
Пример #6
0
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
}
Пример #7
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);
}
Пример #8
0
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);
}
Пример #9
0
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);
    }
}
Пример #10
0
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();
}
Пример #11
0
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);
}