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; }
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; } } }
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; }
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; }
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; }
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()); }
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."); } } } }
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; }
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; }