void MasterStateMachine :: BeforePropose(const int iGroupIdx, std::string & sValue) { std::lock_guard<std::mutex> oLockGuard(m_oMutex); MasterOperator oMasterOper; bool bSucc = oMasterOper.ParseFromArray(sValue.data(), sValue.size()); if (!bSucc) { return; } oMasterOper.set_lastversion(m_llMasterVersion); sValue.clear(); bSucc = oMasterOper.SerializeToString(&sValue); assert(bSucc == true); }
bool MasterStateMachine :: Execute(const int iGroupIdx, const uint64_t llInstanceID, const std::string & sValue, SMCtx * poSMCtx) { MasterOperator oMasterOper; bool bSucc = oMasterOper.ParseFromArray(sValue.data(), sValue.size()); if (!bSucc) { PLG1Err("oMasterOper data wrong"); //wrong oper data, just skip, so return true return true; } if (oMasterOper.operator_() == MasterOperatorType_Complete) { uint64_t * pAbsMasterTimeout = nullptr; if (poSMCtx != nullptr && poSMCtx->m_pCtx != nullptr) { pAbsMasterTimeout = (uint64_t *)poSMCtx->m_pCtx; } uint64_t llAbsMasterTimeout = pAbsMasterTimeout != nullptr ? *pAbsMasterTimeout : 0; PLG1Imp("absmaster timeout %lu", llAbsMasterTimeout); int ret = LearnMaster(llInstanceID, oMasterOper, llAbsMasterTimeout); if (ret != 0) { return false; } } else { PLG1Err("unknown op %u", oMasterOper.operator_()); //wrong op, just skip, so return true; return true; } return true; }
bool MasterStateMachine :: MakeOpValue( const nodeid_t iNodeID, const uint64_t llVersion, const int iTimeout, const MasterOperatorType iOp, std::string & sPaxosValue) { MasterOperator oMasterOper; oMasterOper.set_nodeid(iNodeID); oMasterOper.set_version(llVersion); oMasterOper.set_timeout(iTimeout); oMasterOper.set_operator_(iOp); oMasterOper.set_sid(OtherUtils::FastRand()); return oMasterOper.SerializeToString(&sPaxosValue); }
int MasterStateMachine :: LearnMaster( const uint64_t llInstanceID, const MasterOperator & oMasterOper, const uint64_t llAbsMasterTimeout) { ScopedLock<Mutex> oLockGuard(m_oMutex); if (oMasterOper.version() != m_llMasterVersion) { PLG1Err("version conflit, op version %lu now master version %lu", oMasterOper.version(), m_llMasterVersion); return 0; } int ret = UpdateMasterToStore(oMasterOper.nodeid(), llInstanceID, oMasterOper.timeout()); if (ret != 0) { PLG1Err("UpdateMasterToStore fail, ret %d", ret); return -1; } m_iMasterNodeID = oMasterOper.nodeid(); if (m_iMasterNodeID == m_iMyNodeID) { //self be master //use local abstimeout m_llAbsExpireTime = llAbsMasterTimeout; PLG1Head("Be master success, absexpiretime %lu", m_llAbsExpireTime); } else { //other be master //use new start timeout m_llAbsExpireTime = Time::GetTimestampMS() + oMasterOper.timeout(); PLG1Head("Ohter be master, absexpiretime %lu", m_llAbsExpireTime); } m_iLeaseTime = oMasterOper.timeout(); m_llMasterVersion = llInstanceID; PLG1Imp("OK, masternodeid %lu version %lu abstimeout %lu", m_iMasterNodeID, m_llMasterVersion, m_llAbsExpireTime); return 0; }
int MasterStateMachine :: LearnMaster( const uint64_t llInstanceID, const MasterOperator & oMasterOper, const uint64_t llAbsMasterTimeout) { std::lock_guard<std::mutex> oLockGuard(m_oMutex); PLG1Debug("my last version %lu other last version %lu this version %lu instanceid %lu", m_llMasterVersion, oMasterOper.lastversion(), oMasterOper.version(), llInstanceID); if (oMasterOper.lastversion() != 0 && llInstanceID > m_llMasterVersion && oMasterOper.lastversion() != m_llMasterVersion) { BP->GetMasterBP()->MasterSMInconsistent(); PLG1Err("other last version %lu not same to my last version %lu, instanceid %lu", oMasterOper.lastversion(), m_llMasterVersion, llInstanceID); PLG1Err("try to fix, set my master version %lu as other last version %lu, instanceid %lu", m_llMasterVersion, oMasterOper.lastversion(), llInstanceID); m_llMasterVersion = oMasterOper.lastversion(); } if (oMasterOper.version() != m_llMasterVersion) { PLG1Debug("version conflit, op version %lu now master version %lu", oMasterOper.version(), m_llMasterVersion); return 0; } int ret = UpdateMasterToStore(oMasterOper.nodeid(), llInstanceID, oMasterOper.timeout()); if (ret != 0) { PLG1Err("UpdateMasterToStore fail, ret %d", ret); return -1; } bool bMasterChange = false; if (m_iMasterNodeID != oMasterOper.nodeid()) { bMasterChange = true; } m_iMasterNodeID = oMasterOper.nodeid(); if (m_iMasterNodeID == m_iMyNodeID) { //self be master //use local abstimeout m_llAbsExpireTime = llAbsMasterTimeout; BP->GetMasterBP()->SuccessBeMaster(); PLG1Head("Be master success, absexpiretime %lu", m_llAbsExpireTime); } else { //other be master //use new start timeout m_llAbsExpireTime = Time::GetSteadyClockMS() + oMasterOper.timeout(); BP->GetMasterBP()->OtherBeMaster(); PLG1Head("Ohter be master, absexpiretime %lu", m_llAbsExpireTime); } m_iLeaseTime = oMasterOper.timeout(); m_llMasterVersion = llInstanceID; if (bMasterChange) { if (m_pMasterChangeCallback != nullptr) { m_pMasterChangeCallback(m_iMyGroupIdx, NodeInfo(m_iMasterNodeID), m_llMasterVersion); } } PLG1Imp("OK, masternodeid %lu version %lu abstimeout %lu", m_iMasterNodeID, m_llMasterVersion, m_llAbsExpireTime); return 0; }