///master变化的处理函数 void UnistorHandler4Recv::doEvent(UnistorApp* pApp, UnistorTss* tss, CwxMsgBlock*& msg, CWX_UINT32 uiPoolIndex) { if (EVENT_SEND_MSG == msg->event().getEvent()){ ///发送消息 UnistorHandler4Recv* pHandler =((UnistorRecvThreadUserObj*)tss->getUserObj())->getConn(msg->event().getConnId()); UnistorWriteMsgArg* pWriteArg=(UnistorWriteMsgArg*)msg->event().getConnUserData(); if (pWriteArg){///<存在两种,一种是来自write thread的,一种是来自trans thread的。只有write thead需要释放 msg->event().setConnUserData(NULL); CwxMsgBlockAlloc::free(pWriteArg->m_recvMsg); tss->pushWriteMsgArg(pWriteArg); } if (pHandler){ pHandler->reply(msg, false); msg = NULL; } }else if (CwxEventInfo::CONN_CREATED == msg->event().getEvent()){///连接建立 CwxAppChannel* channel = pApp->getRecvChannels()[uiPoolIndex]; if (channel->isRegIoHandle(msg->event().getIoHandle())){ CWX_ERROR(("Handler[%] is register, it's a big bug, stop.", msg->event().getIoHandle())); pApp->stop(); return; } UnistorHandler4Recv* pHandler = new UnistorHandler4Recv(pApp, pApp->reactor()->getNextConnId(), uiPoolIndex, channel); CwxINetAddr remoteAddr; CwxSockStream stream(msg->event().getIoHandle()); stream.getRemoteAddr(remoteAddr); pHandler->m_unPeerPort = remoteAddr.getPort(); if (remoteAddr.getHostIp(tss->m_szBuf2K, 2047)){ pHandler->m_strPeerHost = tss->m_szBuf2K; } pHandler->setHandle(msg->event().getIoHandle()); pHandler->m_tss = (UnistorTss*)CwxTss::instance(); if (0 != pHandler->open()){ CWX_ERROR(("Failure to register handler[%d] from:%s:%u", pHandler->getHandle(), pHandler->m_strPeerHost.c_str(), pHandler->m_unPeerPort)); delete pHandler; return; } }else if (EVENT_ZK_CONF_CHANGE == msg->event().getEvent()){ UnistorZkConf* pConf = NULL; memcpy(&pConf, msg->rd_ptr(), sizeof(pConf)); if (tss->m_pZkConf){ if (tss->m_pZkConf->m_ullVersion > pConf->m_ullVersion){///<采用旧版本 delete pConf; }else{///采用新版本 delete tss->m_pZkConf; tss->m_pZkConf = pConf; } }else{///<采用新版本 tss->m_pZkConf = pConf; } CWX_INFO(("UnistorHandler4Recv[thread:%u]: ZK config is changed. master_idc:%s, is_master_idc:%s, master_host:%s, is_master=%s, sync_host:%s", tss->m_uiThreadIndex, tss->getMasterIdc(), tss->isMasterIdc()?"yes":"no", tss->getMasterHost(), tss->isMaster()?"yes":"no", tss->getSyncHost())); }else if (EVENT_ZK_LOCK_CHANGE == msg->event().getEvent()){ UnistorZkLock* pLock = NULL; memcpy(&pLock, msg->rd_ptr(), sizeof(pLock)); if (tss->m_pZkLock){ if (tss->m_pZkLock->m_ullVersion > pLock->m_ullVersion){///<采用旧版本 delete pLock; }else{///采用新版本 delete tss->m_pZkLock; tss->m_pZkLock = pLock; } }else{///<采用新版本 tss->m_pZkLock = pLock; } CWX_INFO(("UnistorHandler4Recv[thread:%u]: ZK config is changed. master_idc:%s, is_master_idc:%s, master_host:%s, is_master=%s, sync_host:%s", tss->m_uiThreadIndex, tss->getMasterIdc(), tss->isMasterIdc()?"yes":"no", tss->getMasterHost(), tss->isMaster()?"yes":"no", tss->getSyncHost())); }else{ CWX_ERROR(("Unkwown event type:%d", msg->event().getEvent())); } }
int UnistorHandler4Trans::rebuildConn(UnistorApp* app){ if (!m_strMasterHost.length()){ CWX_INFO(("UnistorHandler4Trans: Master is empty, refuse to connect trans connection.")); } if (!m_bRebuildConn) return 0; CWX_UINT32 ttNow = time(NULL); if (m_ttLastRebuildConn + 2 > ttNow){ return 0; } m_ttLastRebuildConn = ttNow; m_bCanTrans = false; ///关闭已有的所有连接 UnistorHandler4Trans* handle = NULL; map<CWX_UINT32, UnistorHandler4Trans*>::iterator iter = m_handlers->begin(); while(iter != m_handlers->end()){ handle = iter->second; m_handlers->erase(iter); handle->close(); iter = m_handlers->begin(); } m_uiAuthConnNum = 0; CWX_INFO(("UnistorHandler4Trans:Rebuild trans connection to %s:%u, user:passwd=%s:%s", m_strMasterHost.c_str(), app->getConfig().getRecv().getPort(), app->getConfig().getRecv().getUser().length()?app->getConfig().getRecv().getUser().c_str():"", app->getConfig().getRecv().getUser().length()?app->getConfig().getRecv().getUser().c_str():"")); ///重建所有连接 CwxINetAddr addr; if (0 != addr.set(app->getConfig().getRecv().getPort(), m_strMasterHost.c_str())){ CWX_ERROR(("Failure to init addr, addr:%s, port:%u, err=%d", m_strMasterHost.c_str(), app->getConfig().getRecv().getPort(), errno)); return -1; } CWX_UINT32 i=0; int* fds = new int[app->getConfig().getCommon().m_uiTranConnNum]; for (i=0; i<app->getConfig().getCommon().m_uiTranConnNum; i++){ fds[i] = -1; } CwxTimeValue timeout(UNISTOR_CONN_TIMEOUT_SECOND); CwxTimeouter timeouter(&timeout); if (0 != UnistorConnector::connect(addr, app->getConfig().getCommon().m_uiTranConnNum, fds, &timeouter, true, UnistorApp::setConnSockAttr, app->getRecvSockAttr())) { CWX_ERROR(("Failure to connect to addr:%s, port:%u, err=%d",m_strMasterHost.c_str(), app->getConfig().getRecv().getPort(), errno)); return -1; } ///将连接注册到channel CwxAppChannel* channel = app->getTransChannel(); for (i=0; i<app->getConfig().getCommon().m_uiTranConnNum; i++){ if (channel->isRegIoHandle(fds[i])){ CWX_ERROR(("Handler[%] is register", fds[i])); break; } UnistorHandler4Trans* pHandler = new UnistorHandler4Trans(app, app->reactor()->getNextConnId(), channel); pHandler->setHandle(fds[i]); if (0 != pHandler->open()){ pHandler->setHandle(-1); delete pHandler; break; } pHandler->m_tss = (UnistorTss*)CwxTss::instance(); ///<对象对应的tss对象 } if (i < app->getConfig().getCommon().m_uiTranConnNum){ for (CWX_UINT32 j=i; j<app->getConfig().getCommon().m_uiTranConnNum; j++){ ::close(fds[j]); } return -1; } m_bRebuildConn = false; return 0; }
int CwxAppFramework::noticeTcpListen(CWX_UINT32 uiSvrId, char const* szAddr, CWX_UINT16 unPort, bool bRawData, CWX_UINT16 unMode, CWX_NET_SOCKET_ATTR_FUNC fn, void* fnArg, CWX_INT32 iFamily) { if (uiSvrId < SVR_TYPE_USER_START) { CWX_ERROR(("svr-id must not less than SVR_TYPE_USER_START")); return -1; } CWX_UINT32 uiListenId = 0; CwxINetAddr inetAddr; CwxAppTcpAcceptor* acceptor=NULL; uiListenId = m_pListenMgr->getNextListenId(); acceptor = new CwxAppTcpAcceptor(this, reactor(), szAddr, unPort, uiSvrId, uiListenId, bRawData, unMode, fn, fnArg); int ret = 0; if (strcmp(szAddr, "*") == 0){ if (AF_UNSPEC == iFamily) iFamily = AF_INET; ret = inetAddr.set(unPort, iFamily); } else { ret = inetAddr.set(unPort, szAddr, iFamily); } if (0 != ret) { CWX_ERROR(("Address is invalid, tcp listen for ip=%s, port=%u, errno=%d", szAddr, unPort, errno)); return -1; } //register the acceptor if (acceptor->accept(inetAddr) != 0) { CWX_ERROR(("Can't open tcp listen for ip=%s, port=%u, errno=%d", szAddr, unPort, errno)); acceptor->close(); return -1; } if (0 != acceptor->open()) { CWX_ERROR(("Failure to register tcp listen for ip=%s, port=%u", szAddr, unPort)); acceptor->close(); return -1; } //create and init the notice object. CwxAppNotice* notice = new CwxAppNotice(); notice->m_unNoticeType = CwxAppNotice::TCP_LISTEN; notice->m_noticeArg = acceptor; if (0 != m_pReactor->notice(notice)) { acceptor->close(); delete notice; CWX_ERROR(("Failure to notice TCP listen by PIPE")); return -1; } return (int)uiListenId; }
void CwxMqInnerDispHandler::doEvent(CwxMqApp* app, CwxMqTss* tss, CwxMsgBlock*& msg) { if (CwxEventInfo::CONN_CREATED == msg->event().getEvent()) { ///连接建立 CwxAppChannel* channel = app->getInnerDispChannel(); if (channel->isRegIoHandle(msg->event().getIoHandle())) { CWX_ERROR(("Handler[%d] is register, it's a big bug. exit....", msg->event().getIoHandle())); app->stop(); return ; } CwxMqInnerDispHandler* pHandler = new CwxMqInnerDispHandler(app, channel, app->reactor()->getNextConnId()); ///获取连接的来源信息 CwxINetAddr remoteAddr; CwxSockStream stream(msg->event().getIoHandle()); stream.getRemoteAddr(remoteAddr); pHandler->m_unPeerPort = remoteAddr.getPort(); if (remoteAddr.getHostIp(tss->m_szBuf2K, 2047)) { pHandler->m_strPeerHost = tss->m_szBuf2K; } ///设置handle的io后,open handler pHandler->setHandle(msg->event().getIoHandle()); if (0 != pHandler->open()) { CWX_ERROR(("Failure to register sync handler[%d], from:%s:%u", pHandler->getHandle(), pHandler->m_strPeerHost.c_str(), pHandler->m_unPeerPort)); delete pHandler; return ; } ///设置对象的tss对象 pHandler->m_tss = (CwxMqTss*)CwxTss::instance(); CWX_INFO(("Accept inner-sync connection from %s:%u", pHandler->m_strPeerHost.c_str(), pHandler->m_unPeerPort)); } else if (EVENT_ZK_TOPIC_CHANGE == msg->event().getEvent()) { ///topic变化通知 map<string, CWX_UINT8>* changedTopics = NULL; memcpy(&changedTopics, msg->rd_ptr(), sizeof(changedTopics)); if (changedTopics->size()) { map<string, CWX_UINT8>::iterator iter = changedTopics->begin(); for (;iter != changedTopics->end(); iter++) { map<CWX_UINT64, CwxMqInnerDispSession*>::iterator ses_iter = m_sessions.begin(); for (;ses_iter != m_sessions.end();ses_iter++) { ses_iter->second->m_topicIsChanged = true; ///忽略topic/状态改变 if ( iter->second == CWX_MQ_TOPIC_DELETE || ses_iter->second->m_binlogCursor.find(iter->first) != ses_iter->second->m_binlogCursor.end()) continue; {///新增topic CwxBinLogMgr* binlogMgr = app->getTopicMgr()->getBinlogMgrByTopic(iter->first); if (!binlogMgr) { CWX_ERROR(("Failure to get binlogMgr by topic:%s", iter->first.c_str())); break; } CwxBinLogCursor* pCursor = binlogMgr->createCurser(ses_iter->second->m_ullStartSid); if (!pCursor) { CWX_ERROR(("Failure to createCursor by topic:%s", iter->first.c_str())); app->getTopicMgr()->freeBinlogMgrByTopic(iter->first, binlogMgr); break; } CwxBinlogMgrCursor* item = new CwxBinlogMgrCursor(iter->first, binlogMgr, pCursor); ses_iter->second->m_unReadyBinlogCursor.push_back(item); ses_iter->second->m_binlogCursor[iter->first] = item; } } } } delete changedTopics; } else { CWX_ERROR(("Recv unkown event:%d", msg->event().getEvent())); CWX_ASSERT(msg->event().getEvent() == CwxEventInfo::TIMEOUT_CHECK); CWX_ASSERT(msg->event().getSvrId() == CwxMqApp::SVR_TYPE_INNER_DISP); } }