Пример #1
0
int PNode :: InitLogStorage(const Options & oOptions, LogStorage *& poLogStorage)
{
    if (oOptions.poLogStorage != nullptr)
    {
        poLogStorage = oOptions.poLogStorage;
        PLImp("OK, use user logstorage");
        return 0;
    }

    if (oOptions.sLogStoragePath.size() == 0)
    {
        PLErr("LogStorage Path is null");
        return -2;
    }

    int ret = m_oDefaultLogStorage.Init(oOptions.sLogStoragePath, oOptions.iGroupCount);
    if (ret != 0)
    {
        PLErr("Init default logstorage fail, logpath %s ret %d",
                oOptions.sLogStoragePath.c_str(), ret);
        return ret;
    }

    poLogStorage = &m_oDefaultLogStorage;
    
    PLImp("OK, use default logstorage");

    return 0;
}
Пример #2
0
void TcpAcceptor :: run()
{
    PLHead("start accept...");

    m_oSocket.setAcceptTimeout(500);
    m_oSocket.setNonBlocking(true);

    while (true)
    {
        struct pollfd pfd;
        int ret;

        pfd.fd =  m_oSocket.getSocketHandle();
        pfd.events = POLLIN;
        ret = poll(&pfd, 1, 500);

        if (ret != 0 && ret != -1)
        {
            SocketAddress oAddr;
            int fd = -1;
            try
            {
                fd = m_oSocket.acceptfd(&oAddr);
            }
            catch(...)
            {
                fd = -1;
            }
            
            if (fd >= 0)
            {
                BP->GetNetworkBP()->TcpAcceptFd();

                PLImp("accepted!, fd %d ip %s port %d",
                        fd, oAddr.getHost().c_str(), oAddr.getPort());
                AcceptData * poData = new AcceptData;
                poData->fd = fd;
                poData->oAddr = oAddr;
                
                m_oMutex.lock();
                m_oFDQueue.push(poData);
                m_oMutex.unlock();
            }
        }

        ClearEvent();

        if (m_bIsEnd)
        {
            PLHead("TCP.Acceptor [END]");
            return;
        }
    }
}
Пример #3
0
MessageEvent * TcpClient :: CreateEvent(const uint64_t llNodeID, const std::string & sIP, const int iPort)
{
    PLImp("start, ip %s port %d", sIP.c_str(), iPort);

    Socket oSocket;
    oSocket.setNonBlocking(true);
    oSocket.setNoDelay(true);
    SocketAddress oAddr(sIP, iPort);
    oSocket.connect(oAddr);

    MessageEvent * poEvent = new MessageEvent(MessageEventType_SEND, oSocket.detachSocketHandle(), 
            oAddr, m_poEventLoop, m_poNetWork);
    assert(poEvent != nullptr);

    m_mapEvent[llNodeID] = poEvent;
    m_vecEvent.push_back(poEvent);

    PLImp("ok, ip %s port %d", sIP.c_str(), iPort);

    return poEvent;
}
Пример #4
0
int PNode :: InitNetWork(const Options & oOptions, NetWork *& poNetWork)
{
    if (oOptions.poNetWork != nullptr)
    {
        poNetWork = oOptions.poNetWork;
        PLImp("OK, use user network");
        return 0;
    }

    int ret = m_oDefaultNetWork.Init(oOptions.oMyNode.GetIP(), oOptions.oMyNode.GetPort());
    if (ret != 0)
    {
        PLErr("init default network fail, listenip %s listenport %d ret %d",
                oOptions.oMyNode.GetIP().c_str(), oOptions.oMyNode.GetPort(), ret);
        return ret;
    }

    poNetWork = &m_oDefaultNetWork;
    
    PLImp("OK, use default network");

    return 0;
}
Пример #5
0
bool SMFac :: ExecuteForCheckpoint(const int iGroupIdx, const uint64_t llInstanceID, const std::string & sPaxosValue)
{
    if (sPaxosValue.size() < sizeof(int))
    {
        PLErr("Value wrong, instanceid %lu size %zu", llInstanceID, sPaxosValue.size());
        //need do nothing, just skip
        return true;
    }

    int iSMID = 0;
    memcpy(&iSMID, sPaxosValue.data(), sizeof(int));

    if (iSMID == 0)
    {
        PLImp("Value no need to do sm, just skip, instanceid %lu", llInstanceID);
        return true;
    }

    if (m_vecSMList.size() == 0)
    {
        PLImp("No any sm, need wait sm, instanceid %lu", llInstanceID);
        return false;
    }

    for (auto & poSM : m_vecSMList)
    {
        if (poSM->SMID() == iSMID)
        {
            std::string sBodyValue = string(sPaxosValue.data() + sizeof(int), sPaxosValue.size() - sizeof(int));
            return poSM->ExecuteForCheckpoint(iGroupIdx, llInstanceID, sBodyValue);
        }
    }

    PLErr("Unknown smid %d instanceid %lu", iSMID, llInstanceID);

    return false;
}
Пример #6
0
void Learner :: OnAskforLearn(const PaxosMsg & oPaxosMsg)
{
    BP->GetLearnerBP()->OnAskforLearn();
    
    PLGHead("START Msg.InstanceID %lu Now.InstanceID %lu Msg.from_nodeid %lu MinChosenInstanceID %lu", 
            oPaxosMsg.instanceid(), GetInstanceID(), oPaxosMsg.nodeid(),
            m_poCheckpointMgr->GetMinChosenInstanceID());
    
    SetSeenInstanceID(oPaxosMsg.instanceid(), oPaxosMsg.nodeid());

    if (oPaxosMsg.proposalnodeid() == m_poConfig->GetMyNodeID())
    {
        //Found a node follow me.
        PLImp("Found a node %lu follow me.", oPaxosMsg.nodeid());
        m_poConfig->AddFollowerNode(oPaxosMsg.nodeid());
    }
    
    if (oPaxosMsg.instanceid() >= GetInstanceID())
    {
        return;
    }

    if (oPaxosMsg.instanceid() >= m_poCheckpointMgr->GetMinChosenInstanceID())
    {
        if (!m_oLearnerSender.Prepare(oPaxosMsg.instanceid(), oPaxosMsg.nodeid()))
        {
            BP->GetLearnerBP()->OnAskforLearnGetLockFail();

            PLGErr("LearnerSender working for others.");

            if (oPaxosMsg.instanceid() == (GetInstanceID() - 1))
            {
                PLGImp("InstanceID only difference one, just send this value to other.");
                //send one value
                AcceptorStateData oState;
                int ret = m_oPaxosLog.ReadState(m_poConfig->GetMyGroupIdx(), oPaxosMsg.instanceid(), oState);
                if (ret == 0)
                {
                    BallotNumber oBallot(oState.acceptedid(), oState.acceptednodeid());
                    SendLearnValue(oPaxosMsg.nodeid(), oPaxosMsg.instanceid(), oBallot, oState.acceptedvalue(), 0);
                }
            }
            
            return;
        }
    }
    
    SendNowInstanceID(oPaxosMsg.instanceid(), oPaxosMsg.nodeid());
}
Пример #7
0
void PNode :: RunMaster(const Options & oOptions)
{
    for (auto & oGroupSMInfo : oOptions.vecGroupSMInfoList)
    {
        //check if need to run master.
        if (oGroupSMInfo.bIsUseMaster)
        {
            if (!m_vecGroupList[oGroupSMInfo.iGroupIdx]->GetConfig()->IsIMFollower())
            {
                m_vecMasterList[oGroupSMInfo.iGroupIdx]->RunMaster();
            }
            else
            {
                PLImp("I'm follower, not run master damon.");
            }
        }
    }
}
Пример #8
0
int PhxKV :: RunPaxos()
{
    bool bSucc = m_oPhxKVSM.Init();
    if (!bSucc)
    {
        return -1;
    }
    
    Options oOptions;

    oOptions.sLogStoragePath = m_sPaxosLogPath;

    //this groupcount means run paxos group count.
    //every paxos group is independent, there are no any communicate between any 2 paxos group.
    oOptions.iGroupCount = m_iGroupCount;

    oOptions.oMyNode = m_oMyNode;
    oOptions.vecNodeInfoList = m_vecNodeList;

    //because all group share state machine(kv), so every group have same sate machine.
    //just for split key to different paxos group, to upgrate performance.
    for (int iGroupIdx = 0; iGroupIdx < m_iGroupCount; iGroupIdx++)
    {
        GroupSMInfo oSMInfo;
        oSMInfo.iGroupIdx = iGroupIdx;
        oSMInfo.vecSMList.push_back(&m_oPhxKVSM);
        oSMInfo.bIsUseMaster = true;

        oOptions.vecGroupSMInfoList.push_back(oSMInfo);
    }

    //set logfunc
    oOptions.pLogFunc = LOGGER->GetLogFunc();

    int ret = Node::RunNode(oOptions, m_poPaxosNode);
    if (ret != 0)
    {
        PLErr("run paxos fail, ret %d", ret);
        return ret;
    }

    PLImp("run paxos ok\n");
    return 0;
}
Пример #9
0
int MultiDatabase :: Init(const std::string & sDBPath, const int iGroupCount)
{
    if (access(sDBPath.c_str(), F_OK) == -1)
    {
        PLErr("DBPath not exist or no limit to open, %s", sDBPath.c_str());
        return -1;
    }

    if (iGroupCount < 1 || iGroupCount > 100000)
    {
        PLErr("Groupcount wrong %d", iGroupCount);
        return -2;
    }

    std::string sNewDBPath = sDBPath;

    if (sDBPath[sDBPath.size() - 1] != '/')
    {
        sNewDBPath += '/';
    }

    for (int iGroupIdx = 0; iGroupIdx < iGroupCount; iGroupIdx++)
    {
        char sGroupDBPath[512] = {0};
        snprintf(sGroupDBPath, sizeof(sGroupDBPath), "%sg%d", sNewDBPath.c_str(), iGroupIdx);

        Database * poDB = new Database();
        assert(poDB != nullptr);
        m_vecDBList.push_back(poDB);

        if (poDB->Init(sGroupDBPath, iGroupIdx) != 0)
        {
            return -1;
        }
    }

    PLImp("OK, DBPath %s groupcount %d", sDBPath.c_str(), iGroupCount);

    return 0;
}