///发送topic状态表 int CwxMqInnerDispHandler::syncTopicState(CwxMqTss* pTss) { if (m_syncSession->m_topicIsChanged) { map<string, CWX_UINT8> topicState; map<string, CwxBinlogMgrCursor*>::iterator iter = m_syncSession->m_binlogCursor.begin(); while (iter != m_syncSession->m_binlogCursor.end()) { topicState.insert(pair<string, CWX_UINT8>(iter->first, iter->second->m_binlogMgr->getZkTopicState())); CWX_DEBUG(("sync topic:%s, state:%d", iter->first.c_str(), iter->second->m_binlogMgr->getZkTopicState())); iter++; } CwxMsgBlock* pBlock; int ret = CwxMqPoco::packTopicState(pTss->m_pWriter, pTss->m_pItemWriter, pBlock, 0, topicState, pTss->m_szBuf2K); if (ret != CWX_MQ_ERR_SUCCESS) { CWX_ERROR(("Failure to pack topicState err:%s", pTss->m_szBuf2K)); return -1; } ///根据svr类型,发送数据包 pBlock->send_ctrl().setConnId(CWX_APP_INVALID_CONN_ID); pBlock->send_ctrl().setSvrId(CwxMqApp::SVR_TYPE_INNER_DISP); pBlock->send_ctrl().setHostId(0); pBlock->send_ctrl().setMsgAttr(CwxMsgSendCtrl::NONE); if (!putMsg(pBlock)) { CwxCommon::snprintf(pTss->m_szBuf2K, 2047, "Failure to send topicState msg."); CWX_ERROR((pTss->m_szBuf2K)); CwxMsgBlockAlloc::free(pBlock); return -1; } m_syncSession->m_topicIsChanged = false; } return 0; }
int CwxMqApp::monitorStats(char const* buf, CWX_UINT32 uiDataLen, CwxAppHandler4Msg& conn) { string* strCmd = (string*) conn.getConnInfo().getUserData(); strCmd->append(buf, uiDataLen); CwxMsgBlock* msg = NULL; string::size_type end = 0; do { CwxCommon::trim(*strCmd); end = strCmd->find('\n'); if (string::npos == end) { if (strCmd->length() > 10) { //无效的命令 strCmd->erase(); ///清空接受到的命令 ///回复信息 msg = CwxMsgBlockAlloc::malloc(1024); strcpy(msg->wr_ptr(), "ERROR\r\n"); msg->wr_ptr(strlen(msg->wr_ptr())); } else { return 0; } } else { if (memcmp(strCmd->c_str(), "stats", 5) == 0) { strCmd->erase(); ///清空接受到的命令 CWX_UINT32 uiLen = packMonitorInfo(); msg = CwxMsgBlockAlloc::malloc(uiLen); memcpy(msg->wr_ptr(), m_szBuf, uiLen); msg->wr_ptr(uiLen); } else if (memcmp(strCmd->c_str(), "quit", 4) == 0) { return -1; } else { //无效的命令 strCmd->erase(); ///清空接受到的命令 ///回复信息 msg = CwxMsgBlockAlloc::malloc(1024); strcpy(msg->wr_ptr(), "ERROR\r\n"); msg->wr_ptr(strlen(msg->wr_ptr())); } } } while (0); msg->send_ctrl().setConnId(conn.getConnInfo().getConnId()); msg->send_ctrl().setSvrId(CwxMqApp::SVR_TYPE_MONITOR); msg->send_ctrl().setHostId(0); msg->send_ctrl().setMsgAttr(CwxMsgSendCtrl::NONE); if (-1 == sendMsgByConn(msg)) { CWX_ERROR(("Failure to send monitor reply")); CwxMsgBlockAlloc::free(msg); return -1; } return 0; }
int UnistorHandler4Trans::open (void * arg){ m_bAuth = false; int ret = CwxAppHandler4Channel::open(arg); if (0 == ret){ UnistorTss* tss = (UnistorTss*)CwxTss::instance(); ///发送认证消息 CwxMsgBlock* block = NULL; if (UNISTOR_ERR_SUCCESS != UnistorPoco::packRecvAuth(tss->m_pWriter, block, 0, m_pApp->getConfig().getRecv().getUser().length()?m_pApp->getConfig().getRecv().getUser().c_str():"", m_pApp->getConfig().getRecv().getPasswd().length()?m_pApp->getConfig().getRecv().getPasswd().c_str():"", tss->m_szBuf2K)) { CWX_ERROR(("Failure to pack recv auth package, err=%s", tss->m_szBuf2K)); ret = channel()->removeHandler(this); if (0 != ret){ CWX_ERROR(("Failure to remove handler from channel")); } return -1; } (*m_handlers)[m_uiConnId] = this; block->send_ctrl().setMsgAttr(CwxMsgSendCtrl::NONE); ///发送消息 putMsg(block); } return 0; }
/** @brief Handler的redo事件,在每次dispatch时执行。 @return -1:处理失败,会调用close(); 0:处理成功 */ int CwxMqInnerDispHandler::onRedo() { ///发送下一条binlog int iState = syncSendBinLog(m_tss); if (-1 == iState) { CWX_ERROR(("%s, from:%s:%u", m_tss->m_szBuf2K, m_strPeerHost.c_str(), m_unPeerPort)); CwxMsgBlock* msg = NULL; if (CWX_MQ_ERR_ERROR != CwxMqPoco::packSyncErr(m_tss->m_pWriter, msg, m_header.getTaskId(), CWX_MQ_ERR_ERROR, m_tss->m_szBuf2K, m_tss->m_szBuf2K)) { CWX_ERROR(("Failure to pack sync data reply, err=%s, from:%s:%u", m_tss->m_szBuf2K, m_strPeerHost.c_str(), m_unPeerPort)); return -1; } msg->send_ctrl().setMsgAttr(CwxMsgSendCtrl::CLOSE_NOTICE); if (!putMsg(msg)) { CwxMsgBlockAlloc::free(msg); CWX_ERROR(("Failure push msg to send queue. from:%s:%u", m_strPeerHost.c_str(), m_unPeerPort)); return -1; } } else if (0 == iState) { ///产生continue的消息 channel()->regRedoHander(this); } return 0; }
///echo请求的处理函数 int CwxEchoEventHandler::onRecvMsg(CwxMsgBlock*& msg, CwxTss* ) { ///设置echo回复的消息类型,为请求的消息类型+1 msg->event().getMsgHeader().setMsgType(msg->event().getMsgHeader().getMsgType() + 1); ///设置echo回复的数据包长度 msg->event().getMsgHeader().setDataLen(msg->length()); ///创建回复的数据包 CwxMsgBlock* pBlock = CwxMsgBlockAlloc::malloc(msg->length() + CwxMsgHead::MSG_HEAD_LEN); ///拷贝数据包的包头 memcpy(pBlock->wr_ptr(), msg->event().getMsgHeader().toNet(), CwxMsgHead::MSG_HEAD_LEN); ///滑动block的写指针 pBlock->wr_ptr(CwxMsgHead::MSG_HEAD_LEN); ///拷贝数据包的数据 memcpy(pBlock->wr_ptr(), msg->rd_ptr(), msg->length()); ///滑动block的写指针 pBlock->wr_ptr(msg->length()); ///设置回复消息的发送控制信息 pBlock->send_ctrl().reset(); ///设置回复消息对应连接的svr-id pBlock->send_ctrl().setSvrId(msg->event().getSvrId()); ///设置回复消息对应连接的host-id pBlock->send_ctrl().setHostId(msg->event().getHostId()); ///设置回复消息的连接id pBlock->send_ctrl().setConnId(msg->event().getConnId()); ///回复消息 if (0 != this->m_pApp->sendMsgByConn(pBlock)) { CWX_ERROR(("Failure to send msg")); return -1; } m_ullMsgNum ++; if (m_ullMsgNum && !(m_ullMsgNum%10000)) { char szBuf[64]; CwxCommon::toString(m_ullMsgNum, szBuf, 10); CWX_INFO(("Recv echo message num:%s", szBuf)); } return 1; }
///notice send msg by svr void CwxAppFramework::innerNoticeSendMsgBySvr(CwxAppFramework* pApp, CwxAppNotice* pNotice) { CwxMsgBlock* msg = (CwxMsgBlock*)pNotice->m_noticeArg; if (0 != pApp->onSendMsgBySvr(msg)) { if (msg->send_ctrl().isFailNotice()) { pApp->onFailSendMsg(msg); } if (msg) CwxMsgBlockAlloc::free(msg); } pNotice->m_noticeArg = NULL; }
///notice send msg void CwxAppFramework::innerNoticeSendMsgByConn(CwxAppFramework* pApp, CwxAppNotice* pNotice) { CwxMsgBlock* msg = (CwxMsgBlock*)pNotice->m_noticeArg; CwxAppHandler4Msg* pConn = (CwxAppHandler4Msg*)pApp->m_pReactor->getHandlerByConnId(msg->send_ctrl().getConnId()); if (!pConn || (CwxAppConnInfo::ESTABLISHED != pConn->getConnInfo().getState())) { if (msg->send_ctrl().isFailNotice()) { pApp->onFailSendMsg(msg); } if (msg) CwxMsgBlockAlloc::free(msg); pNotice->m_noticeArg = NULL; return; } if (!msg->send_ctrl().isUndoConn()) { int ret = 0; if (msg->send_ctrl().isResumeConn()) { ret = pConn->reactor()->resumeHandler(pConn, CwxAppHandler4Base::READ_MASK); if (0 != ret) { CWX_ERROR(("Failure to resume handler, conn_id=[%u]", msg->send_ctrl().getConnId())); pConn->close(); } } else if (msg->send_ctrl().isSuspendConn()) { ret = pConn->reactor()->suspendHandler(pConn, CwxAppHandler4Base::READ_MASK); if (0 != ret) { CWX_ERROR(("Failure to resume handler, conn_id=[%u]", msg->send_ctrl().getConnId())); pConn->close(); } } } if (!pConn->putMsg(msg)) { if (msg->send_ctrl().isFailNotice()) { pApp->onFailSendMsg(msg); } if (msg) CwxMsgBlockAlloc::free(msg); pNotice->m_noticeArg = NULL; } }
///往master转发消息 bool UnistorHandler4Trans::transMsg(UnistorTss* , CWX_UINT32 uiTaskId, CwxMsgBlock* msg){ CwxMsgBlock* block = NULL; ///如果没有完成认证的连接,则失败 if (!m_uiAuthConnNum) return false; ///往master转发消息 block = CwxMsgBlockAlloc::malloc(CwxMsgHead::MSG_HEAD_LEN + msg->length()); CwxMsgHead header(msg->event().getMsgHeader()); header.setDataLen(msg->length()); header.setTaskId(uiTaskId); CWX_UINT8 ucAttr=header.getAttr(); header.setAttr(UnistorPoco::clearFromMaster(ucAttr)); memcpy(block->wr_ptr(), header.toNet(), CwxMsgHead::MSG_HEAD_LEN); memcpy(block->wr_ptr() + CwxMsgHead::MSG_HEAD_LEN, msg->rd_ptr(), msg->length()); block->wr_ptr( CwxMsgHead::MSG_HEAD_LEN + msg->length()); block->event().setTaskId(uiTaskId); block->send_ctrl().setMsgAttr(CwxMsgSendCtrl::FAIL_FINISH_NOTICE); if (!m_authConn[msg->event().getConnId()%m_uiAuthConnNum]->putMsg(block)){ CwxMsgBlockAlloc::free(block); return false; } return true; }
///echo请求的处理函数 int CwxMqRecvHandler::onRecvMsg(CwxMsgBlock*& msg, CwxTss* pThrEnv) { CwxMqTss* pTss = (CwxMqTss*) pThrEnv; if (!m_bCanWrite) { CWX_ERROR(("I am not master, can't recv msg so close it.")); m_pApp->noticeCloseConn(msg->event().getConnId()); return 1; } int iRet = CWX_MQ_ERR_SUCCESS; CWX_UINT64 ullSid = 0; do { ///binlog数据接收消息 if (CwxMqPoco::MSG_TYPE_RECV_DATA == msg->event().getMsgHeader().getMsgType()) { CwxKeyValueItem const* pData; char const* szTopic; if (!msg) { strcpy(pTss->m_szBuf2K, "No data."); CWX_DEBUG((pTss->m_szBuf2K)); iRet = CWX_MQ_ERR_ERROR; break; } unsigned long ulUnzipLen = 0; bool bZip = msg->event().getMsgHeader().isAttr(CwxMsgHead::ATTR_COMPRESS); //判断是否压缩数据 if (bZip) { //压缩数据,需要解压 //首先准备解压的buf if (!prepareUnzipBuf()) { iRet = CWX_MQ_ERR_ERROR; CwxCommon::snprintf(pTss->m_szBuf2K, 2047, "Failure to prepare unzip buf, size:%u", m_uiBufLen); CWX_ERROR((pTss->m_szBuf2K)); break; } ulUnzipLen = m_uiBufLen; //解压 if (!CwxZlib::unzip(m_unzipBuf, ulUnzipLen, (const unsigned char*) msg->rd_ptr(), msg->length())) { iRet = CWX_MQ_ERR_ERROR; CwxCommon::snprintf(pTss->m_szBuf2K, 2047, "Failure to unzip recv msg, msg size:%u, buf size:%u", msg->length(), m_uiBufLen); CWX_ERROR((pTss->m_szBuf2K)); break; } } if (CWX_MQ_ERR_SUCCESS != (iRet = CwxMqPoco::parseRecvData(pTss->m_pReader, bZip ? (char const*) m_unzipBuf : msg->rd_ptr(), bZip ? ulUnzipLen : msg->length(), pData, szTopic, pTss->m_szBuf2K))) { iRet = CWX_MQ_ERR_ERROR; //如果是无效数据,返回 CWX_ERROR(("Failure to parse the recieve msg, err=%s", pTss->m_szBuf2K)); break; } CwxBinLogMgr* binlogMgr = NULL; map<string, CwxBinLogMgr*>::iterator iter = m_binlogMgr.find(szTopic); if (iter == m_binlogMgr.end()) { binlogMgr = m_pApp->getTopicMgr()->getBinlogMgrByTopic(szTopic, true); if (!binlogMgr){ CwxCommon::snprintf(pTss->m_szBuf2K, 2047, "Invalid topic:%s", szTopic); CWX_ERROR((pTss->m_szBuf2K)); iRet = CWX_MQ_ERR_ERROR; break; } m_binlogMgr[szTopic] = binlogMgr; }else { binlogMgr = iter->second; } if (binlogMgr->getZkTopicState() != CWX_MQ_TOPIC_NORMAL) { CwxCommon::snprintf(pTss->m_szBuf2K, 2047, "Invlaid topic : %s.", szTopic); CWX_ERROR((pTss->m_szBuf2K)); iRet = CWX_MQ_ERR_ERROR; ///删除binlogMgr引用 m_binlogMgr.erase(szTopic); m_pApp->getTopicMgr()->freeBinlogMgrByTopic(szTopic, binlogMgr); break; } pTss->m_pWriter->beginPack(); pTss->m_pWriter->addKeyValue(CWX_MQ_D, pData->m_szData, pData->m_uiDataLen, pData->m_bKeyValue); pTss->m_pWriter->pack(); if (m_pApp->getCurSid() == 0) { m_pApp->setCurSid(CWX_MQ_MAX_BINLOG_FLUSH_COUNT + 1); } ullSid = m_pApp->nextSid(); CWX_UINT32 timestamp = time(NULL); if (0 != binlogMgr->append(ullSid, timestamp, 0, pTss->m_pWriter->getMsg(), pTss->m_pWriter->getMsgSize(), pTss->m_szBuf2K)) { CWX_ERROR((pTss->m_szBuf2K)); iRet = CWX_MQ_ERR_ERROR; break; } m_pApp->setCurTimestamp(timestamp); if (m_pApp->getStartSid() == 0) { m_pApp->setStartSid(ullSid); } } else { CwxCommon::snprintf(pTss->m_szBuf2K, 2047, "Invalid msg type:%u", msg->event().getMsgHeader().getMsgType()); CWX_ERROR((pTss->m_szBuf2K)); iRet = CWX_MQ_ERR_ERROR; break; } } while (0); CwxMsgBlock* pBlock = NULL; if (CWX_MQ_ERR_SUCCESS != CwxMqPoco::packRecvDataReply(pTss->m_pWriter, pBlock, msg->event().getMsgHeader().getTaskId(), iRet, ullSid, pTss->m_szBuf2K, pTss->m_szBuf2K)) { CWX_ERROR(("Failure to pack mq reply msg, err=%s", pTss->m_szBuf2K)); m_pApp->noticeCloseConn(msg->event().getConnId()); return 1; } pBlock->send_ctrl().setConnId(msg->event().getConnId()); pBlock->send_ctrl().setSvrId(CwxMqApp::SVR_TYPE_RECV); pBlock->send_ctrl().setHostId(0); pBlock->send_ctrl().setMsgAttr(CwxMsgSendCtrl::NONE); if (0 != m_pApp->sendMsgByConn(pBlock)) { CWX_ERROR(("Failure to reply error msg")); CwxMsgBlockAlloc::free(pBlock); m_pApp->noticeCloseConn(msg->event().getConnId()); } return 1; }
///0:未发送一条binlog; ///1:发送了一条binlog; ///-1:失败; int CwxMqInnerDispHandler::syncSendBinLog(CwxMqTss* pTss) { int iRet = 0; CwxMsgBlock* pBlock = NULL; CWX_UINT32 uiKeyLen = 0; CWX_UINT32 uiTotalLen = 0; CWX_UINT64 ullSeq = m_syncSession->m_ullSeq; if (m_syncSession->m_topicIsChanged) { syncTopicState(pTss); } if (m_syncSession->m_uiChunk) pTss->m_pWriter->beginPack(); while (1) { if (m_syncSession->m_unReadyBinlogCursor.size()) { if (syncSeekToReportSid(pTss) != 0) return -1; } if (1 != (iRet = syncSeekToBinlog(pTss))) break; //设置移到下一个记录位置 m_syncSession->m_bNext = true; if (!m_syncSession->m_uiChunk) { iRet = syncPackOneBinLog(pTss->m_pWriter, pBlock, ullSeq, pTss->m_pBinlogData, pTss->m_szBuf2K); m_ullLastSid = m_syncSession->m_pBinlogCursor->m_pCursor->getHeader().getSid(); break; } else { iRet = syncPackMultiBinLog(pTss->m_pWriter, pTss->m_pItemWriter, pTss->m_pBinlogData, uiKeyLen, pTss->m_szBuf2K); m_ullLastSid = m_syncSession->m_pBinlogCursor->m_pCursor->getHeader().getSid(); if (1 == iRet) { uiTotalLen += uiKeyLen; if (uiTotalLen >= m_syncSession->m_uiChunk) break; } if (-1 == iRet) break; continue; } } if (-1 == iRet) return -1; if (!m_syncSession->m_uiChunk) { ///若不是chunk if (0 == iRet) return 0; ///没有数据 } else { if (0 == uiTotalLen) return 0; pTss->m_pWriter->pack(); if (CWX_MQ_ERR_SUCCESS != CwxMqPoco::packMultiSyncData(0, pTss->m_pWriter->getMsg(), pTss->m_pWriter->getMsgSize(), pBlock, ullSeq, m_syncSession->m_bZip, pTss->m_szBuf2K)) { return -1; } } ///根据svr类型,发送数据包 pBlock->send_ctrl().setConnId(CWX_APP_INVALID_CONN_ID); pBlock->send_ctrl().setSvrId(CwxMqApp::SVR_TYPE_INNER_DISP); pBlock->send_ctrl().setHostId(0); pBlock->send_ctrl().setMsgAttr(CwxMsgSendCtrl::NONE); if (!putMsg(pBlock)) { CwxCommon::snprintf(pTss->m_szBuf2K, 2047, "Failure to send binlog"); CWX_ERROR((pTss->m_szBuf2K)); CwxMsgBlockAlloc::free(pBlock); return -1; } m_ullSendSeq = ullSeq; m_syncSession->m_ullSeq++; return 1; ///发送了一条消息 }
int CwxMqInnerDispHandler::recvReply(CwxMqTss* pTss) { int iRet = CWX_MQ_ERR_SUCCESS; CWX_UINT64 ullSeq = 0; CwxMsgBlock* msg = NULL; do { if (!m_syncSession) { ///如果连接不是同步状态,则是错误 strcpy(pTss->m_szBuf2K, "Client no in sync state"); CWX_ERROR(("%s, from:%s:%u", pTss->m_szBuf2K, m_strPeerHost.c_str(), m_unPeerPort)); iRet = CWX_MQ_ERR_ERROR; break; } if (!m_recvMsgData) { strcpy(pTss->m_szBuf2K, "No data."); CWX_ERROR(("Sync reply package is empty, from:%s:%u", m_strPeerHost.c_str(), m_unPeerPort)); iRet = CWX_MQ_ERR_ERROR; break; } ///若是同步sid的报告消息,则获取报告的sid iRet = CwxMqPoco::parseSyncDataReply(pTss->m_pReader, m_recvMsgData, ullSeq, pTss->m_szBuf2K); if (CWX_MQ_ERR_SUCCESS != iRet) { CWX_ERROR(("Failure to parse sync_data reply package, err:%s, from:%s:%u", pTss->m_szBuf2K, m_strPeerHost.c_str(), m_unPeerPort)); break; } if (ullSeq != m_ullSendSeq) { char szTmp1[64]; char szTmp2[64]; iRet = CWX_MQ_ERR_ERROR; CwxCommon::snprintf(pTss->m_szBuf2K, 2047, "Seq[%s] is not same with the connection's[%s].", CwxCommon::toString(ullSeq, szTmp1, 10), CwxCommon::toString(m_ullSendSeq, szTmp2, 10)); CWX_ERROR(("%s, from:%s:%u", pTss->m_szBuf2K, m_strPeerHost.c_str(), m_unPeerPort)); break; } ///发送下一条binlog int iState = syncSendBinLog(pTss); if (-1 == iState) { CWX_ERROR(("%s, from:%s:%u", pTss->m_szBuf2K, m_strPeerHost.c_str(), m_unPeerPort)); return -1; ///关闭连接 } else if (0 == iState) { ///产生continue的消息 channel()->regRedoHander(this); } return 0; } while (0); ///到此一定错误 CWX_ASSERT(CWX_MQ_ERR_SUCCESS != iRet); if (CWX_MQ_ERR_SUCCESS != CwxMqPoco::packSyncErr(pTss->m_pWriter, msg, m_header.getTaskId(), iRet, pTss->m_szBuf2K, pTss->m_szBuf2K)) { CWX_ERROR(("Failure to pack sync data reply, err=%s, from:%s:%u", pTss->m_szBuf2K, m_strPeerHost.c_str(), m_unPeerPort)); return -1; } msg->send_ctrl().setMsgAttr(CwxMsgSendCtrl::CLOSE_NOTICE); if (!putMsg(msg)) { CwxMsgBlockAlloc::free(msg); CWX_ERROR(("Failure push msg to send queue. from:%s:%u", m_strPeerHost.c_str(), m_unPeerPort)); return -1; } return 0; }
int CwxMqInnerDispHandler::recvNewConnection(CwxMqTss* pTss) { int iRet = 0; CWX_UINT64 ullSession = 0; CwxMsgBlock* msg = NULL; do { if (!m_recvMsgData) { strcpy(pTss->m_szBuf2K, "No data."); CWX_ERROR(("Session connect-report package is empty, from:%s:%u", m_strPeerHost.c_str(), m_unPeerPort)); iRet = CWX_MQ_ERR_ERROR; break; } ///禁止重复report sid。若cursor存在,表示已经报告过一次 if (m_syncSession) { iRet = CWX_MQ_ERR_ERROR; CwxCommon::snprintf(pTss->m_szBuf2K, 2048, "Can't report sync sid duplicatly."); CWX_ERROR(("Session connect-report is duplicate, from:%s:%u", m_strPeerHost.c_str(), m_unPeerPort)); break; } ///获取报告的session id iRet = CwxMqPoco::parseReportNewConn(pTss->m_pReader, m_recvMsgData, ullSession, pTss->m_szBuf2K); if (CWX_MQ_ERR_SUCCESS != iRet) { CWX_ERROR(("Failure to parse report new conn msg, err=%s, from:%s:%u", pTss->m_szBuf2K, m_strPeerHost.c_str(), m_unPeerPort)); break; } if (m_sessions.find(ullSession) == m_sessions.end()) { iRet = CWX_MQ_ERR_ERROR; char szTmp[64]; CwxCommon::snprintf(pTss->m_szBuf2K, 2048, "Session[%s] doesn't exist.", CwxCommon::toString(ullSession, szTmp, 10)); CWX_ERROR(("%s, from:%s:%u", pTss->m_szBuf2K, m_strPeerHost.c_str(), m_unPeerPort)); break; } m_syncSession = m_sessions.find(ullSession)->second; m_ullSessionId = m_syncSession->m_ullSessionId; m_syncSession->addConn(this); ///发送下一条binlog int iState = syncSendBinLog(pTss); if (-1 == iState) { iRet = CWX_MQ_ERR_ERROR; CWX_ERROR(("%s, from:%s:%u", pTss->m_szBuf2K, m_strPeerHost.c_str(), m_unPeerPort)); break; } else if (0 == iState) { ///产生continue消息 channel()->regRedoHander(this); } return 0; } while(0); ///到此一定错误 CWX_ASSERT(CWX_MQ_ERR_SUCCESS != iRet); if (CWX_MQ_ERR_SUCCESS != CwxMqPoco::packSyncErr(pTss->m_pWriter, msg, m_header.getTaskId(), iRet, pTss->m_szBuf2K, pTss->m_szBuf2K)) { CWX_ERROR(("Failure to pack sync data reply, err=%s, from:%s:%u", pTss->m_szBuf2K, m_strPeerHost.c_str(), m_unPeerPort)); return -1; } msg->send_ctrl().setMsgAttr(CwxMsgSendCtrl::CLOSE_NOTICE); if (!putMsg(msg)) { CwxMsgBlockAlloc::free(msg); CWX_ERROR(("Failure push msg to send queue. from:%s:%u", m_strPeerHost.c_str(), m_unPeerPort)); return -1; } return 0; }
int CwxMqInnerDispHandler::recvReport(CwxMqTss* pTss) { int iRet = 0; CWX_UINT64 ullSid = 0; CWX_UINT32 uiChunk = 0; bool bZip = false; CwxMsgBlock* msg = NULL; do { if (!m_recvMsgData) { strcpy(pTss->m_szBuf2K, "No data."); CWX_ERROR(("Report package is empty, from:%s:%u", m_strPeerHost.c_str(), m_unPeerPort)); iRet = CWX_MQ_ERR_ERROR; break; } ///禁止重复report sid。若cunsor存在,表示已经报告过一次 if (m_syncSession) { iRet = CWX_MQ_ERR_ERROR; CwxCommon::snprintf(pTss->m_szBuf2K, 2048, "Can't report sync sid duplicate."); CWX_ERROR(("Report is duplicate, from:%s:%u", m_strPeerHost.c_str(), m_unPeerPort)); break; } ///若是同步sid的报告消息,则获取报告sid iRet = CwxMqPoco::parseInnerReportData(pTss->m_pReader, m_recvMsgData, ullSid, uiChunk, bZip, pTss->m_szBuf2K); if (CWX_MQ_ERR_SUCCESS != iRet) { CWX_ERROR(("Failure to parse report msg, err=%s, from:%s:%u", pTss->m_szBuf2K, m_strPeerHost.c_str(), m_unPeerPort)); break; } CWX_INFO(("Report info :%s:%u, sid=%s, chunk=%u, zip=%s", m_strPeerHost.c_str(), m_unPeerPort, CwxCommon::toString(ullSid, pTss->m_szBuf2K, 10), uiChunk, bZip?"yes":"no")); m_syncSession = new CwxMqInnerDispSession(m_pApp); m_syncSession->m_strHost = m_strPeerHost; m_syncSession->m_uiChunk = uiChunk; m_syncSession->m_bZip = bZip; if (m_syncSession->m_uiChunk) { if (m_syncSession->m_uiChunk > CwxMqConfigCmn::MAX_CHUNK_SIZE_KB) m_syncSession->m_uiChunk = CwxMqConfigCmn::MAX_CHUNK_SIZE_KB; if (m_syncSession->m_uiChunk < CwxMqConfigCmn::MIN_CHUNK_SIZE_KB) m_syncSession->m_uiChunk = CwxMqConfigCmn::MIN_CHUNK_SIZE_KB; m_syncSession->m_uiChunk *= 1024; } m_syncSession->reformSessionId(); ///将session加到session的map while (m_sessions.find(m_syncSession->m_ullSessionId) != m_sessions.end()) { m_syncSession->reformSessionId(); } m_sessions[m_syncSession->m_ullSessionId] = m_syncSession; m_ullSessionId = m_syncSession->m_ullSessionId; m_syncSession->addConn(this); if (0 != m_syncSession->init()) { CWX_ERROR(("Failure to init session min heap.")); break; } ///回复iRet的值 iRet = CWX_MQ_ERR_SUCCESS; ///创建binlog的读取cursor list<string> topics; m_pApp->getTopicMgr()->getAllTopics(topics); for(list<string>::iterator iter = topics.begin(); iter != topics.end(); iter++) { CwxBinLogMgr* binlogMgr = m_pApp->getTopicMgr()->getBinlogMgrByTopic(*iter); if (!binlogMgr) { ///binlogMgr被删除 CWX_ERROR(("Failure to get BinloMgr topic:%s", iter->c_str())); continue; } CwxBinLogCursor* pCursor = binlogMgr->createCurser(ullSid); if (!pCursor) { iRet = CWX_MQ_ERR_ERROR; strcpy(pTss->m_szBuf2K, "Failure to create cursor"); CWX_ERROR(("%s, from:%s:%u", pTss->m_szBuf2K, m_strPeerHost.c_str(), m_unPeerPort)); m_pApp->getTopicMgr()->freeBinlogMgrByTopic(*iter, binlogMgr); break; } CwxBinlogMgrCursor* item = new CwxBinlogMgrCursor(*iter, binlogMgr, pCursor); m_syncSession->m_binlogCursor[*iter] = item; m_syncSession->m_unReadyBinlogCursor.push_back(item); } m_syncSession->m_ullStartSid = ullSid; ///发送session id的消息 if (CWX_MQ_ERR_SUCCESS != CwxMqPoco::packReportDataReply(pTss->m_pWriter, msg, m_header.getTaskId(), m_syncSession->m_ullSessionId, pTss->m_szBuf2K)) { CWX_ERROR(("Failure to pack sync data reply, err=%s, from:%s:%u", pTss->m_szBuf2K, m_strPeerHost.c_str(), m_unPeerPort)); return -1; } msg->send_ctrl().setMsgAttr(CwxMsgSendCtrl::NONE); if (!putMsg(msg)) { CwxMsgBlockAlloc::free(msg); CWX_ERROR(("Failure push msg to send queue. from:%s:%u", m_strPeerHost.c_str(), m_unPeerPort)); return -1; } ///发送发一条binlog int iState = syncSendBinLog(pTss); if (-1 == iState) { iRet = CWX_MQ_ERR_ERROR; CWX_ERROR(("%s, from:%s:%u", pTss->m_szBuf2K, m_strPeerHost.c_str(), m_unPeerPort)); break; } else if (0 == iState) { ///产生continue的消息 channel()->regRedoHander(this); } return 0; }while(0); ///到此一定错误 CWX_ASSERT(CWX_MQ_ERR_SUCCESS != iRet); CwxMsgBlock* pBlock = NULL; if (CWX_MQ_ERR_SUCCESS != CwxMqPoco::packSyncErr(pTss->m_pWriter, pBlock, m_header.getTaskId(), iRet, pTss->m_szBuf2K, pTss->m_szBuf2K)) { CWX_ERROR(("Failure to create binlog reply package, err:%s", pTss->m_szBuf2K)); return -1; } pBlock->send_ctrl().setMsgAttr(CwxMsgSendCtrl::CLOSE_NOTICE); if (!putMsg(pBlock)) { CwxMsgBlockAlloc::free(pBlock); CWX_ERROR(("Failure push msg to send queue. from:%s:%u", m_strPeerHost.c_str(), m_unPeerPort)); return -1; } return 0; }