void UnistorHandler4Trans::checkTrans(UnistorApp* app, UnistorTss* tss){ CWX_INFO(("UnistorHandler4Trans: ZK config is changed. master_idc:%s, is_master_idc:%s, master_host:%s, is_master=%s, sync_host:%s", tss->getMasterIdc(), tss->isMasterIdc()?"yes":"no", tss->getMasterHost(), tss->isMaster()?"yes":"no", tss->getSyncHost())); bool bTrans = false; string strTransMaster = ""; if (tss->m_pZkConf && tss->m_pZkLock){ if (tss->m_pZkConf->m_bMasterIdc){///如果是master idc if (!tss->m_pZkLock->m_bMaster){ bTrans = true; strTransMaster = tss->m_pZkLock->m_strMaster; }else{ bTrans = false; } }else{ bTrans = false; } } if (!bTrans){ ///关闭已有的所有连接 map<CWX_UINT32, UnistorHandler4Trans*>::iterator iter = m_handlers->begin(); while(iter != m_handlers->end()){ iter->second->close(); iter = m_handlers->begin(); } CWX_ASSERT(m_handlers->size()==0); m_strMasterHost = ""; m_uiAuthConnNum = 0; m_bRebuildConn = false; m_bCanTrans = false; }else{ if (strTransMaster != m_strMasterHost){ map<CWX_UINT32, UnistorHandler4Trans*>::iterator iter = m_handlers->begin(); while(iter != m_handlers->end()){ iter->second->close(); iter = m_handlers->begin(); } CWX_ASSERT(m_handlers->size()==0); m_strMasterHost = strTransMaster; m_uiAuthConnNum = 0; m_bRebuildConn = true; m_bCanTrans = false; rebuildConn(app); } } }
int CwxAppEpoll::registerSignal(int signum, CwxAppHandler4Base *event_handler) { if (!m_bEnableSignal) { CWX_ASSERT(0); CWX_ERROR(("Epoll engine not support signal")); return -1; } if ((signum < 0) || (signum >= CWX_APP_MAX_SIGNAL_ID)) { CWX_ERROR(("Invalid signal id[%d], range[0,%d]", signum, CWX_APP_MAX_SIGNAL_ID)); return -1; } if (m_sHandler[signum]) { CWX_ERROR(("Signal[%d] exist.", signum)); return -1; } struct sigaction sa; //set stop hander sa.sa_handler = 0; sa.sa_sigaction = CwxAppEpoll::sigAction; sigemptyset(&sa.sa_mask); sa.sa_flags =SA_SIGINFO; if (-1 == sigaction(signum, &sa, NULL)) { CWX_ERROR(("Failure register signal[%d] handler.", signum)); return -1; } event_handler->setHandle(signum); m_sHandler[signum] = event_handler; return 0; }
///用户自定义事件处理函数 int CwxMqRecvHandler::onUserEvent(CwxMsgBlock*& msg, CwxTss* pThrEnv) { CWX_ASSERT(m_pApp->getConfig().getCommon().m_type == CwxMqConfigCmn::MQ_TYPE_ZK); CwxMqTss* pTss = (CwxMqTss*)pThrEnv; if (EVENT_ZK_LOCK_CHANGE == msg->event().getEvent()) { ///master发生切换 CwxMqZkLock* pLock = NULL; memcpy(&pLock, msg->rd_ptr(), sizeof(&pLock)); if (pTss->m_pZkLock) { if (pTss->m_pZkLock->m_ullVersion > pLock->m_ullVersion) { ///采用旧版本 delete pLock; }else { ///采用新版本 delete pTss->m_pZkLock; pTss->m_pZkLock = pLock; } }else { ///采用新版本 pTss->m_pZkLock = pLock; } CWX_INFO(("CwxMqRecvHandler: lock changed.master[%s:%s:%d], prev[%s:%s:%d]", pTss->m_pZkLock->m_strMaster.c_str(), pTss->m_pZkLock->m_strMasterInnerDispHost.c_str(), pTss->m_pZkLock->m_unMasterInnerDispPort, pTss->m_pZkLock->m_strPrev.c_str(), pTss->m_pZkLock->m_strPrevInnerDispHost.c_str(), pTss->m_pZkLock->m_unPrevInnerDispPort)); configChange(pTss); }else { CWX_ERROR(("CwxMqRecvHandler: unknown event type:%u", msg->event().getEvent())); return 0; } return 1; }
int CwxAppFramework::init(int argc, char** argv) { int iRet = parse(argc, argv); if (0 != iRet) { help(); return iRet; } if ( this->m_bCmdStop || this->m_bCmdRestart) return 0; this->destroy(); if (0 != CwxTss::initTss()) { CWX_ERROR(("Failure to init tss")); return -1; } //get app name CwxFile::getLastDirName(argv[0], m_strAppName); m_pTss = this->onTssEnv(); CWX_ASSERT(m_pTss); m_pTss->getThreadInfo().setStartTime(time(NULL)); m_pTss->getThreadInfo().setUpdateTime(time(NULL)); m_pTss->getThreadInfo().setThreadNo(0); CwxTss::regTss(m_pTss); return 0; }
CwxAppHandler4Base* CwxAppEpoll::removeSignal(int signum) { if (!m_bEnableSignal) { CWX_ASSERT(0); CWX_ERROR(("Epoll engine not support signal")); return NULL; } if ((signum < 0) || (signum >= CWX_APP_MAX_SIGNAL_ID)) { CWX_ERROR(("Invalid signal id[%d], range[0,%d]", signum, CWX_APP_MAX_SIGNAL_ID)); return NULL; } if (!m_sHandler[signum]) { CWX_ERROR(("Signal[%d] doesn't exist.", signum)); return NULL; } CwxAppHandler4Base* handler = m_sHandler[signum]; struct sigaction sa; //set stop hander sa.sa_handler = SIG_DFL; sigemptyset(&sa.sa_mask); sa.sa_flags =0x0; sigaction(signum, &sa, NULL); m_sHandler[signum] = NULL; return handler; }
int CwxAppFramework::hook(void* arg) { CwxAppFramework* pApp = (CwxAppFramework*)arg; if (!pApp->isStopped()){ ///分发事件 pApp->noticeEvent(); //invoke the hook if (pApp->m_bEnableHook) pApp->onHook(); //dispatch the fork event if (pApp->m_forkMgr.isForkEvent()){ list<CwxAppForkEnv*> forks; pid_t src_pid = getpid(); pid_t curPid = 0; pApp->m_forkMgr.getForkEnvs(forks); list<CwxAppForkEnv*>::iterator iter = forks.begin(); CwxAppForkEnv* pForkEnv = NULL; while(iter != forks.end()){ pForkEnv = *iter; curPid = pForkEnv->onFork(); if (-1 == curPid){ CWX_ERROR(("Failure to fork")); }else if (0 == curPid){//child CWX_ASSERT(src_pid != getpid()); iter++; //delete the fork event in child process while(iter != forks.end()){ delete *iter; iter++; } pApp->m_bStopped = true; pApp->m_pReactor->forkReinit(); //invoke child pForkEnv->onChildEntry(pApp); pApp->destroy(); pForkEnv->onChildMain(); delete pForkEnv; return -1; } CWX_ASSERT(src_pid == getpid()); delete *iter; //it's parent iter++; } } } return 0; }
///检测超时的元素,key的expire时间超过uiCurTime的全部失效 void UnistorStoreMemCache::checkExpire(CWX_UINT32 uiCurTime, CWX_UINT32 uiBatchNum){ CWX_UINT32 uiSlot=m_uiCurCheckSlotIndex; CWX_UINT32 uiPos=m_uiCurCheckSlotPos; CWX_UINT32 uiTotalSlot = m_cacheBufArrIndex + 1; CWX_UINT32 uiCheckNum = 0; UnistorStoreMemCacheItem* key=NULL; m_uiExpireNum = 0; for (; uiSlot<uiTotalSlot; uiSlot++){ while(UNISTOR_STORE_MEM_CACHE_SLOT_SIZE >= uiPos + sizeof(UnistorStoreMemCacheItem)){ key = (UnistorStoreMemCacheItem*)(m_cacheBufArr[uiSlot] + uiPos); if (UnistorStoreMemCacheItem::UNISTOR_MEM_ITEM_STATE_UNMALLOC == key->m_ucState){ break;///<剩余的空间没有分配 }else if (UnistorStoreMemCacheItem::UNISTOR_MEM_ITEM_STATE_USED == key->m_ucState){ if (key->m_uiExpire && (key->m_uiExpire < uiCurTime)){///<疑似超时 m_arrExpiredItem[m_uiExpireNum++] = key; } } uiCheckNum++; uiPos += key->size(); ///如果已经检查了指定的数量,则break。 if (uiCheckNum >= m_uiMaxPerCheckExpireNum) break; } ///如果已经检查了指定的数量,则break。 if (uiCheckNum >= m_uiMaxPerCheckExpireNum) break; uiPos = 0;///<从头开始 } ///如果已经满了,则break if (uiCheckNum < m_uiMaxPerCheckExpireNum){ ///本轮检测全部完成 CWX_ASSERT(uiSlot == uiTotalSlot); m_uiCurCheckSlotIndex = 0; m_uiCurCheckSlotPos = 0; }else{ m_uiCurCheckSlotIndex = uiSlot; m_uiCurCheckSlotPos = uiPos; } CWX_UINT32 uiIndex = 0; UnistorStoreMemCacheIter iter; while(uiIndex < m_uiExpireNum){ if (uiIndex + uiBatchNum > m_uiExpireNum){ uiBatchNum = m_uiExpireNum - uiIndex; } { ///获取写锁 CwxWriteLockGuard<CwxRwLock> lock(&m_rwLock); for (CWX_UINT32 i=0; i<uiBatchNum; i++){ iter.m_uiHash = UnistorStoreMemCacheItem::m_fnHash(m_arrExpiredItem[uiIndex]->getKey(), m_arrExpiredItem[uiIndex]->getKeyLen())%m_bucket_num; if (_findKey(m_arrExpiredItem[uiIndex], iter) && m_arrExpiredItem[uiIndex]->m_uiExpire && (m_arrExpiredItem[uiIndex]->m_uiExpire < uiCurTime)){ _remove(iter); } uiIndex++; } } } m_uiExpireNum = 0; }
///分发mq channel的队列消息函数。返回值:0:正常;-1:队列停止 int CwxMqApp::dealMqFetchThreadQueueMsg(CwxMsgQueue* queue, CwxMqApp* app, CwxAppChannel* channel) { int iRet = 0; CwxMsgBlock* block = NULL; CwxAppHandler4Channel* handler = NULL; while (!queue->isEmpty()) { do { iRet = queue->dequeue(block); if (-1 == iRet) return -1; if ((block->event().getEvent() == CwxEventInfo::CONN_CREATED) && (block->event().getSvrId() == SVR_TYPE_QUEUE)) { if (channel->isRegIoHandle(block->event().getIoHandle())) { CWX_ERROR(("Handler[%] is register", block->event().getIoHandle())); break; } if (block->event().getSvrId() == SVR_TYPE_QUEUE) { handler = new CwxMqQueueHandler(app, channel); } else { CWX_ERROR(("Invalid svr_type[%d], close handle[%d]", block->event().getSvrId(), block->event().getIoHandle())); ::close(block->event().getIoHandle()); } handler->setHandle(block->event().getIoHandle()); if (0 != handler->open()) { CWX_ERROR(("Failure to register handler[%d]", handler->getHandle())); delete handler; break; } } else { CWX_ASSERT(block->event().getEvent() == CwxEventInfo::TIMEOUT_CHECK); CWX_ASSERT(block->event().getSvrId() == SVR_TYPE_QUEUE); app->getQueueMgr()->timeout(app->getCurTime()); } } while (0); CwxMsgBlockAlloc::free(block); block = NULL; } if (queue->isDeactived()) return -1; return 0; }
void CwxBinlogOp::doRecord(CWX_UINT32 uiRecord) { int iRet = 0; CWX_UINT64 offset = 0; printf("Seeking to binlog, record index=%u\n", uiRecord); map<CWX_UINT32/*rec_no*/, CWX_UINT32/*offset*/>::iterator iter; if (uiRecord + 1 > m_uiRecNum) { printf("Record Index[%u] doesn't exist, total record is %u\n", uiRecord, m_uiRecNum); return; } iter = m_recIndex.lower_bound(uiRecord + 1); CWX_ASSERT(iter != m_recIndex.end()); CWX_UINT32 uiRecordSkip = 0; if (iter->first == uiRecord + 1) { offset = iter->second; uiRecordSkip = 0; } else { iter--; CWX_ASSERT(iter != m_recIndex.end()); offset = iter->second; uiRecordSkip = uiRecord + 1 - iter->first; } CWX_UINT64 ullOldSid = m_pCursor->getHeader().getOffset(); if (1 != m_pCursor->seek(offset)) { printf("Failure to seek binlog, error:%s\n", m_pCursor->getErrMsg()); m_pCursor->seek(ullOldSid); return; } while (uiRecordSkip) { iRet = m_pCursor->next(); if (0 == iRet) { printf("Skip to end.\n"); return; } else if (0 > iRet) { printf("Failure to seek binlog, record index [%u], err=%s\n", uiRecord, m_pCursor->getErrMsg()); m_pCursor->seek(ullOldSid); return; } uiRecordSkip--; } }
int CwxAppEpoll::removeSignal(CwxAppHandler4Base *event_handler) { if (!m_bEnableSignal) { CWX_ASSERT(0); CWX_ERROR(("Epoll engine not support signal")); return -1; } removeSignal(event_handler->getHandle()); return 0; }
//false:错误;true:解包正确。通过GetError()获取失败的原因。 bool CwxPackageReaderEx::unpack(char const* szMsg, CWX_UINT32 uiMsgLen, bool bIndex, bool bCaseSensive) { int iRet = 0; reset(); m_uiPackBufLen = uiMsgLen; m_szPackMsg = szMsg; m_bIndex = bIndex; m_bCaseSensive = bCaseSensive; if (0 == uiMsgLen) return true; CwxCharCaseLess2 cmp(m_bCaseSensive); m_pKeyIndex = new CWX_PACKAGE_KEY_MAP(cmp); iRet = CwxPackageEx::getKeyValueNum(szMsg, uiMsgLen); if (0 > iRet) { strcpy(this->m_szErr, "It's not a valid package"); return false; } m_uiKeyNum = iRet; if (m_uiTotalKeyNum < m_uiKeyNum) { if (m_pKeyValue) delete [] m_pKeyValue; m_uiTotalKeyNum = (m_uiKeyNum + KEY_VALUE_ALIGN -1)/KEY_VALUE_ALIGN; m_uiTotalKeyNum *= KEY_VALUE_ALIGN; m_pKeyValue = new CwxKeyValueItemEx[m_uiTotalKeyNum]; memset(m_pKeyValue, 0x00, sizeof(CwxKeyValueItemEx) * m_uiTotalKeyNum); } CWX_UINT32 uiPos = 0; CWX_UINT32 uiIndex = 0; while(uiPos < m_uiPackBufLen) { if (uiIndex == m_uiKeyNum) { CwxCommon::snprintf(this->m_szErr, ERR_MSG_LEN, "The package should be kv[%u], but exceed.", m_uiKeyNum); CWX_ASSERT(0); return false; } if (-1 == (iRet = CwxPackageEx::getNextKey(this->m_szPackMsg + uiPos, m_uiPackBufLen - uiPos, this->m_pKeyValue[uiIndex]))) { CwxCommon::snprintf(this->m_szErr, ERR_MSG_LEN, "Can't get the %dth key/value", uiIndex); return false; } if (0 == iRet) break; //finish if (m_bIndex) (*m_pKeyIndex)[this->m_pKeyValue[uiIndex].m_szKey] = &this->m_pKeyValue[uiIndex]; uiIndex ++; uiPos += iRet; if (uiPos == uiMsgLen) return true; //finish. } return true; }
int CwxAppEpoll::registerHandler(CWX_HANDLE handle, CwxAppHandler4Base *event_handler, int mask, CWX_UINT32 uiMillSecond) { if ((handle < 0) || (handle >= CWX_APP_MAX_IO_NUM)) { CWX_ERROR(("Invalid io handle id[%d], range[0,%d]", handle, CWX_APP_MAX_IO_NUM)); return -1; } ///若handle相等,是fork后的重新添加 if (m_eHandler[handle].m_handler) { CWX_ERROR(("handler is registered, handle[%d]", (int)handle)); return -1; } mask &=CwxAppHandler4Base::IO_MASK; ///只支持READ、WRITE、PERSIST、TIMEOUT四种掩码 if (uiMillSecond) mask |= CwxAppHandler4Base::TIMEOUT_MASK; if (uiMillSecond) { CWX_ASSERT(-1 == event_handler->index()); event_handler->m_ullTimeout = CwxDate::getTimestamp(); event_handler->m_ullTimeout += uiMillSecond * 1000; if (!m_timeHeap.push(event_handler)) { CWX_ERROR(("Failure to add handler to time-heap, io[%d]", handle)); return -1; } } if (mask&CwxAppHandler4Base::RW_MASK) ///如果存在READ、WRITE的掩码,则注册 { if (0 != addEvent(handle, mask)) { if (uiMillSecond) m_timeHeap.erase(event_handler); ///删除timeout return -1; } } m_eHandler[handle].m_handler = event_handler; m_eHandler[handle].m_mask = mask; return 0; }
///echo请求的请求消息 int CwxEchoApp::onRecvMsg(CwxMsgBlock* msg, CwxAppHandler4Msg& conn, CwxMsgHead const& header, bool& bSuspendConn){ msg->event().setSvrId(conn.getConnInfo().getSvrId()); msg->event().setHostId(conn.getConnInfo().getHostId()); msg->event().setConnId(conn.getConnInfo().getConnId()); msg->event().setIoHandle(conn.getHandle()); msg->event().setConnUserData(NULL); msg->event().setMsgHeader(header); msg->event().setEvent(CwxEventInfo::RECV_MSG); msg->event().setTimestamp(CwxDate::getTimestamp()); ///不停止继续接受 bSuspendConn = false; CWX_ASSERT (msg); ///将消息放到线程池队列中,有内部的线程调用其处理handle来处理 m_threadPool->append(msg); return 0; }
///收到消息的响应函数 int CwxMqApp::onRecvMsg(CwxAppHandler4Msg& conn, bool&) { if (SVR_TYPE_MONITOR == conn.getConnInfo().getSvrId()) { char szBuf[1024]; ssize_t recv_size = CwxSocket::recv(conn.getHandle(), szBuf, 1024); if (recv_size <= 0) { //error or signal if ((0 == recv_size) || ((errno != EWOULDBLOCK) && (errno != EINTR))) { return -1; //error } else { //signal or no data return 0; } } ///监控消息 return monitorStats(szBuf, (CWX_UINT32) recv_size, conn); } else { CWX_ASSERT(0); } return -1; }
int CwxAppFramework::init(char const* app_name) { parse(); if ( this->m_bCmdStop || this->m_bCmdRestart) return 0; this->destroy(); if (0 != CwxTss::initTss()) { CWX_ERROR(("Failure to init tss")); return -1; } //get app name CwxFile::getLastDirName(app_name, m_strAppName); m_pTss = this->onTssEnv(); CWX_ASSERT(m_pTss); m_pTss->getThreadInfo().setStartTime(time(NULL)); m_pTss->getThreadInfo().setUpdateTime(time(NULL)); m_pTss->getThreadInfo().setThreadNo(0); CwxTss::regTss(m_pTss); return 0; }
///连接关闭 int CwxMqApp::onConnClosed(CwxAppHandler4Msg& conn) { if ((SVR_TYPE_RECV == conn.getConnInfo().getSvrId()) || (SVR_TYPE_MASTER == conn.getConnInfo().getSvrId())) { CwxMsgBlock* pBlock = CwxMsgBlockAlloc::malloc(0); pBlock->event().setSvrId(conn.getConnInfo().getSvrId()); pBlock->event().setHostId(conn.getConnInfo().getHostId()); pBlock->event().setConnId(conn.getConnInfo().getConnId()); ///设置事件类型 pBlock->event().setEvent(CwxEventInfo::CONN_CLOSED); m_recvThreadPool->append(pBlock); } else if (SVR_TYPE_MONITOR == conn.getConnInfo().getSvrId()) { ///若是监控的连接关闭,则必须释放先前所创建的string对象。 if (conn.getConnInfo().getUserData()) { delete (string*) conn.getConnInfo().getUserData(); conn.getConnInfo().setUserData(NULL); } } else { CWX_ASSERT(0); } return 0; }
///连接建立 int CwxMqApp::onConnCreated(CwxAppHandler4Msg& conn, bool&, bool&) { if ((SVR_TYPE_RECV == conn.getConnInfo().getSvrId()) || (SVR_TYPE_MASTER == conn.getConnInfo().getSvrId())) { CwxMsgBlock* pBlock = CwxMsgBlockAlloc::malloc(0); pBlock->event().setSvrId(conn.getConnInfo().getSvrId()); pBlock->event().setHostId(conn.getConnInfo().getHostId()); pBlock->event().setConnId(conn.getConnInfo().getConnId()); ///设置事件类型 pBlock->event().setEvent(CwxEventInfo::CONN_CREATED); ///将事件添加到消息队列 m_recvThreadPool->append(pBlock); } else if (SVR_TYPE_MONITOR == conn.getConnInfo().getSvrId()) { ///如果是监控的连接建立,则建立一个string的buf,用于缓存不完整的命令 string* buf = new string(); conn.getConnInfo().setUserData(buf); } else { CWX_ASSERT(0); } return 0; }
///收到消息 int CwxMqApp::onRecvMsg(CwxMsgBlock* msg, CwxAppHandler4Msg& conn, CwxMsgHead const& header, bool&) { if ((SVR_TYPE_RECV == conn.getConnInfo().getSvrId()) || (SVR_TYPE_MASTER == conn.getConnInfo().getSvrId())) { msg->event().setSvrId(conn.getConnInfo().getSvrId()); msg->event().setHostId(conn.getConnInfo().getHostId()); msg->event().setConnId(conn.getConnInfo().getConnId()); ///保存消息头 msg->event().setMsgHeader(header); ///设置事件类型 msg->event().setEvent(CwxEventInfo::RECV_MSG); ///将消息放到线程池队列中,有内部的线程调用其处理handle来处理 m_recvThreadPool->append(msg); return 0; } else { CWX_ASSERT(0); } return 0; }
int CwxMqApp::onConnCreated(CWX_UINT32 uiSvrId, CWX_UINT32 uiHostId, CWX_HANDLE handle, bool&) { CwxMsgBlock* msg = CwxMsgBlockAlloc::malloc(0); msg->event().setSvrId(uiSvrId); msg->event().setHostId(uiHostId); msg->event().setConnId(CWX_APP_INVALID_CONN_ID); msg->event().setIoHandle(handle); msg->event().setEvent(CwxEventInfo::CONN_CREATED); ///将消息放到线程池队列中,有内部的线程调用其处理handle来处理 if (SVR_TYPE_DISP == uiSvrId) { if (m_dispThreadPool->append(msg) <= 1) m_dispChannel->notice(); } else if (SVR_TYPE_QUEUE == uiSvrId) { if (m_mqThreadPool->append(msg) <= 1) m_mqChannel->notice(); } else { CWX_ASSERT(SVR_TYPE_MONITOR == uiSvrId); } return 0; }
///释放关闭的session void CwxMqInnerDispHandler::dealClosedSession(CwxMqApp* app, CwxMqTss* ) { list<CwxMqInnerDispSession*>::iterator iter; CwxMqInnerDispHandler* handler; ///获取用户object对象 if (m_freeSession.begin() != m_freeSession.end()) { iter = m_freeSession.begin(); while (iter != m_freeSession.end()) { CwxMqInnerDispSession* session = *iter; ///session必须是closed状态 CWX_ASSERT((*iter)->m_bClosed); CWX_INFO(("Close sync session from host:%s", (*iter)->m_strHost.c_str())); if (session->m_binlogCursor.size()) { map<string, CwxBinlogMgrCursor*>::iterator cursor_iter = session->m_binlogCursor.begin(); while(cursor_iter != session->m_binlogCursor.end()) { cursor_iter->second->m_binlogMgr->destoryCurser(cursor_iter->second->m_pCursor); app->getTopicMgr()->freeBinlogMgrByTopic(cursor_iter->first, cursor_iter->second->m_binlogMgr); delete cursor_iter->second; cursor_iter++; } session->m_binlogCursor.clear(); } ///将session从session的map中删除 m_sessions.erase((*iter)->m_ullSessionId); ///开始关闭连接 map<CWX_UINT32, CwxMqInnerDispHandler*>::iterator conn_iter = (*iter)->m_conns.begin(); while (conn_iter != (*iter)->m_conns.end()) { handler = conn_iter->second; (*iter)->m_conns.erase(handler->getConnId()); handler->close(); ///此为同步调用 conn_iter = (*iter)->m_conns.begin(); } delete *iter; iter++; } m_freeSession.clear(); } }
///添加一个新连接 void CwxMqInnerDispSession::addConn(CwxMqInnerDispHandler* conn) { CWX_ASSERT(m_conns.find(conn->getConnId()) == m_conns.end()); m_conns[conn->getConnId()] = conn; }
void CwxBinlogOp::doSid(CWX_UINT64 ullSid) { int iRet = 0; CWX_UINT64 offset = 0; char szBuf1[64], szBuf2[64]; printf("Seeking to binlog, sid=%s\n", CwxCommon::toString(ullSid, szBuf1)); map<CWX_UINT64/*sid*/, CWX_UINT32/*offset*/>::iterator iter; if (ullSid < m_ullMinSid) { printf("Sid[%s] is less than min sid[%s], it doesn't exist\n", CwxCommon::toString(ullSid, szBuf1), CwxCommon::toString(m_ullMinSid, szBuf2)); return; } if (ullSid > m_ullMaxSid) { printf("Sid[%s] is more than max sid[%s], it doesn't exist\n", CwxCommon::toString(ullSid, szBuf1), CwxCommon::toString(m_ullMaxSid, szBuf2)); return; } iter = m_sidIndex.lower_bound(ullSid); CWX_ASSERT(iter != m_sidIndex.end()); if (iter->first == ullSid) { offset = iter->second; } else { iter--; CWX_ASSERT(iter != m_sidIndex.end()); offset = iter->second; } CWX_UINT32 i = 0; CWX_UINT64 ullOldSid = m_pCursor->getHeader().getOffset(); bool bFind = false; if (1 != m_pCursor->seek(offset)) { printf("Failure to seek binlog, error:%s\n", m_pCursor->getErrMsg()); m_pCursor->seek(ullOldSid); return; } for (i = 0; i < BINLOG_INDEX_INTERNAL; i++) { if (m_pCursor->getHeader().getSid() == ullSid) { bFind = true; printf("Find sid=%s\n", CwxCommon::toString(ullSid, szBuf1)); return; } iRet = m_pCursor->next(); if (1 == iRet) continue; if (0 == iRet) { printf("Can't find sid=%s\n", CwxCommon::toString(ullSid, szBuf1)); m_pCursor->seek(ullOldSid); return; } else if (0 > iRet) { printf("Failure to seek binlog, err=%s\n", m_pCursor->getErrMsg()); m_pCursor->seek(ullOldSid); return; } } printf("Can't find binlog, sid=%s\n", CwxCommon::toString(ullSid, szBuf1)); m_pCursor->seek(ullOldSid); }
int CwxAppHandler4Channel::onOutput () { int result = 0; bool bCloseConn = false; // The list had better not be empty, otherwise there's a bug! if (NULL == this->m_curSndingMsg) { CWX_ASSERT(m_uiSendByte==0); while(1) { result = this->getNextMsg(); if (0 == result) return this->cancelWakeup(); if (CWX_CHECK_ATTR(this->m_curSndingMsg->send_ctrl().getMsgAttr(), CwxMsgSendCtrl::BEGIN_NOTICE)) { if (-1 == onStartSendMsg(m_curSndingMsg)) { CwxMsgBlockAlloc::free(this->m_curSndingMsg); this->m_curSndingMsg = NULL; continue; //next msg; } }//end if (this->m_curSndingMsg->IsBeginNotice()) //it's a msg which need be sent. break; //break while }//end while } //has message result = this->nonBlockSend(); if (0 == result) {// Partial send. CWX_ASSERT (errno == EWOULDBLOCK); return 0; } else if (1 == result) {//finish bCloseConn = CWX_CHECK_ATTR(this->m_curSndingMsg->send_ctrl().getMsgAttr(), CwxMsgSendCtrl::CLOSE_NOTICE); this->m_uiSendByte = 0; if (CWX_CHECK_ATTR(this->m_curSndingMsg->send_ctrl().getMsgAttr(), CwxMsgSendCtrl::FINISH_NOTICE)){ CWX_UINT32 uiResume = onEndSendMsg(m_curSndingMsg); if (CwxMsgSendCtrl::RESUME_CONN == uiResume) { if (0 != channel()->resumeHandler(this, CwxAppHandler4Base::READ_MASK)) { CWX_ERROR(("Failure to resume handler with conn_id[%d]", getHandle())); return -1; } } else if (CwxMsgSendCtrl::SUSPEND_CONN == uiResume) { if (0 != channel()->suspendHandler(this, CwxAppHandler4Base::READ_MASK)) { CWX_ERROR(("Failure to suspend handler with conn_id[%d]", getHandle())); return -1; } } } if (bCloseConn) { return -1; } if (m_curSndingMsg) { CwxMsgBlockAlloc::free(m_curSndingMsg); this->m_curSndingMsg = NULL; } return 0; } else {//failure if (m_curSndingMsg->send_ctrl().isFailNotice()) { onFailSendMsg(m_curSndingMsg); } if (m_curSndingMsg) CwxMsgBlockAlloc::free(m_curSndingMsg); this->m_curSndingMsg = NULL; return -1; } return -1; }
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; }
void UnistorStoreMemCache::insert(char const* szKey, CWX_UINT16 unKeyLen, char const* szData, CWX_UINT32 uiDataLen, CWX_UINT32* uiExpire) { ///key的长度不能为0 if (!unKeyLen) return; CWX_UINT32 uiOldExpire = 0; CWX_UINT32 uiIndex = 0; char key_buf[UnistorStoreMemCacheItem::calKeySize(unKeyLen , 0)]; UnistorStoreMemCacheItem* key = (UnistorStoreMemCacheItem*)key_buf; memcpy(key->m_szBuf, szKey, unKeyLen); key->m_unKeyLen = unKeyLen; UnistorStoreMemCacheIter iter; CWX_UINT32 uiKeySize = UnistorStoreMemCacheItem::calKeySize(unKeyLen , uiDataLen); ///若key的空间大小大于slot,则不cache if (uiKeySize > UNISTOR_STORE_MEM_CACHE_MAX_ITEM_SIZE) return; iter.m_uiHash = UnistorStoreMemCacheItem::m_fnHash(key->getKey(), key->getKeyLen())%m_bucket_num; { CwxWriteLockGuard<CwxRwLock> lock(&m_rwLock); ///如果key存在 if(_findKey(key, iter)){ if (uiKeySize == iter.m_pFind->size()){///属于同一个slot ///修改空间 m_usedDataSize -= iter.m_pFind->getDataLen(); m_usedDataSize += uiDataLen; iter.m_pFind->m_uiDataLen = uiDataLen; if (uiExpire) iter.m_pFind->m_uiExpire = *uiExpire; if (uiDataLen){ memcpy((char*)iter.m_pFind->getData(), szData, uiDataLen); } uiIndex = iter.m_pFind->index(); _touch(iter.m_pFind, uiIndex); return; } uiOldExpire = iter.m_pFind->m_uiExpire; ///属于不同的slot,首先溢出,此时拥有hash锁、链表锁、及统计锁 _remove(iter); } ///计算索引 uiIndex = UnistorStoreMemCacheItem::calKeyIndex(unKeyLen , uiDataLen); ///优先使用空闲的key if (m_chainArr[uiIndex].m_freeHead){ key = m_chainArr[uiIndex].m_freeHead; m_chainArr[uiIndex].m_freeHead = m_chainArr[uiIndex].m_freeHead->m_next; ///修改空间 m_chainArr[uiIndex].m_uiFreeNum--; m_freeSize -= uiKeySize; m_freeCapacity -= (uiKeySize - sizeof(UnistorStoreMemCacheItem)); m_freeItemCount --; }else if ((m_cacheBufArrIndex + 1 < m_cacheBufArrSize) || ///从新内存分配key (m_cacheBufArrPos + uiKeySize < UNISTOR_STORE_MEM_CACHE_SLOT_SIZE)) { if (m_cacheBufArrPos + uiKeySize > UNISTOR_STORE_MEM_CACHE_SLOT_SIZE){///<使用新slot m_cacheBufArrIndex ++; m_cacheBufArrPos = 0; } ///分配新空间 key = (UnistorStoreMemCacheItem*)(m_cacheBufArr[m_cacheBufArrIndex] + m_cacheBufArrPos); m_cacheBufArrPos += uiKeySize; }else if (m_chainArr[uiIndex].m_usedTail){///释放已有空间 key = m_chainArr[uiIndex].m_usedTail; iter.m_uiHash = UnistorStoreMemCacheItem::m_fnHash(key->getKey(), key->getKeyLen())%m_bucket_num; _findKey(key, iter); if (iter.m_pFind != key){ CWX_ASSERT(0); } ///从hash中删除key _removeKey(iter); m_chainArr[uiIndex].m_usedTail = m_chainArr[uiIndex].m_usedTail->m_prev; if (!m_chainArr[uiIndex].m_usedTail){ m_chainArr[uiIndex].m_usedHead = NULL; }else{ m_chainArr[uiIndex].m_usedTail->m_next = NULL; } m_chainArr[uiIndex].m_uiUsedNum--; m_usedSize -= uiKeySize; m_usedCapacity -= uiKeySize - sizeof(UnistorStoreMemCacheItem); m_usedDataSize -= key->m_uiDataLen + key->m_unKeyLen; m_cachedKeyCount--; m_cachedItemCount--; }else{ ///没有空间可用,不cache return ; } ///copy数据 key->m_uiKeyIndex = uiIndex; ///<设置key的index key->m_unKeyLen = unKeyLen; key->m_uiDataLen = uiDataLen; key->m_ucState = UnistorStoreMemCacheItem::UNISTOR_MEM_ITEM_STATE_USED; key->m_uiExpire = uiExpire?*uiExpire:uiOldExpire; if (unKeyLen) memcpy((char*)key->getKey(), szKey, unKeyLen); if (uiDataLen) memcpy((char*)key->getData(), szData, uiDataLen); _addKey(uiIndex, uiKeySize, key); } }
int CwxAppFramework::noticeFork(CwxAppForkEnv* pForkEnv){ CWX_ASSERT(pForkEnv); m_forkMgr.append(pForkEnv); 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::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; }
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); } }
///handle close int CwxAppHandler4UnixConn::close(CWX_HANDLE ) { CWX_UINT16 ucLocState = m_conn.getState(); char const* szState; int iCloseReturn=0; if (getApp()->isStopped()) { if (-1 != this->index()) reactor()->cancelTimer(this); delete this; return 0; } switch(ucLocState) { case CwxAppConnInfo::IDLE: szState = "IDLE"; ///一定没有在reactor注册 break; case CwxAppConnInfo::CONNECTING: szState = "CONNECTING";///可能在重连的时候再reactor注册 CWX_ERROR(("Failure to connect to unix-file:%s, errno=%d", m_strConnectPathFile.c_str(), getConnErrNo())); if (reactor()) reactor()->removeHandler(this); break; case CwxAppConnInfo::TIMEOUT: szState = "TIMEOUT"; ///可能注册了timeout if (-1 != this->index()) reactor()->cancelTimer(this); break; case CwxAppConnInfo::ESTABLISHING: szState = "ESTABLISHING";///可能注册了消息收发 if (CWX_INVALID_HANDLE != getHandle()) if (reactor()) reactor()->removeHandler(this, false); break; case CwxAppConnInfo::ESTABLISHED: szState = "ESTABLISHED";///一定注册了消息收发 if (CWX_INVALID_HANDLE != getHandle()) if (reactor()) reactor()->removeHandler(this, false); break; case CwxAppConnInfo::FAILED: szState = "FAILED";///一定没有注册消息收发 break; default: szState = "Unknown"; CWX_ASSERT(0); break; } if (CWX_INVALID_HANDLE != getHandle()) { CWX_DEBUG(("Connection closed. State = %s, unix file=%s, Active-Close=%s", szState, m_strConnectPathFile.c_str(), m_conn.isActiveClose()?"yes":"no")); } m_conn.setState(CwxAppConnInfo::FAILED); //reconnection or close if (CwxAppConnInfo::ESTABLISHED == ucLocState) { //re-dispatch all msg while(this->getNextMsg() == 1) { if (this->m_curSndingMsg && m_curSndingMsg->send_ctrl().isFailNotice()) { this->getApp()->onFailSendMsg(m_curSndingMsg); } if (m_curSndingMsg) CwxMsgBlockAlloc::free(m_curSndingMsg); this->m_curSndingMsg = NULL; } iCloseReturn = this->getApp()->connClosed(*this); m_conn.setFailConnNum(1); //remove recieved data. if (this->m_recvMsgData) CwxMsgBlockAlloc::free(this->m_recvMsgData); this->m_recvMsgData = NULL; } else if (m_conn.isActiveConn()) { m_conn.setFailConnNum(m_conn.getFailConnNum() + 1); iCloseReturn = this->getApp()->onFailConnect(*this); } if (getHandle () != CWX_INVALID_HANDLE) { ::close(getHandle()); setHandle(CWX_INVALID_HANDLE); } if (m_conn.isNeedReconnect() && (iCloseReturn>=0)) { CWX_UINT32 uiInternal = 0; if (m_conn.isReconn()) { uiInternal = m_conn.getReconnDelay(); m_conn.setReconn(false); } else { if (iCloseReturn > 0) { uiInternal = iCloseReturn; } else { uiInternal = 2 * m_conn.getMinRetryInternal() * getConnInfo().getFailConnNum(); if (uiInternal > getConnInfo().getMaxRetryInternal()) uiInternal = getConnInfo().getMaxRetryInternal(); uiInternal *= 1000; } } CWX_DEBUG(("Reconnect to address %s after %d mili-second.", m_strConnectPathFile.c_str(), uiInternal)); if (uiInternal) { m_conn.setState(CwxAppConnInfo::TIMEOUT); if (this->reactor()->scheduleTimer(this, CwxTimeValue(uiInternal/1000, (uiInternal%1000) * 1000)) == -1) { CWX_ERROR(("Failure schedule_timer to noticeReconnect for conn id[%u]", m_conn.getConnId())); if (reactor()) reactor()->removeHandlerByConnId(m_conn.getConnId()); delete this; return 0; } } else { if (-1 == getApp()->getUnixConnector()->connect(this, m_strConnectPathFile.c_str())) { CWX_ERROR(("Failure to reconnect unix-file=%s, errno=%d", m_strConnectPathFile.c_str(), errno)); this->close(); } } } else { reactor()->removeFromConnMap(m_conn.getConnId()); getApp()->getHandlerCache()->cacheUnixHandle(this); } return 0; }