///notice noticeReconnect void CwxAppFramework::innerNoticeReconnect(CwxAppFramework* pApp, CwxAppNotice* pNotice) { CWX_UINT32 uiConnId = (CWX_UINT32)((size_t)(pNotice->m_noticeArg)); CWX_UINT32 uiDelay = (CWX_UINT32)((size_t)(pNotice->m_noticeArg1)); CwxAppHandler4Msg * pConn = (CwxAppHandler4Msg*)pApp->m_pReactor->getHandlerByConnId(uiConnId); if (!pConn) { CWX_ERROR(("Execute closing connect by conn_id[%u], it doesn't exist", uiConnId)); return ; } if (!pConn->getConnInfo().isActiveConn()) { CWX_ERROR(("Execute closing connect by conn_id[%u], it's not active conn", uiConnId)); return ; } if (CwxAppConnInfo::CONNECTING == pConn->getConnInfo().getState()) { CWX_DEBUG(("Conn[%s] is waiting connect, don't reconnect")); return; } pConn->getConnInfo().setActiveClose(false); pConn->getConnInfo().setReconn(true); pConn->getConnInfo().setReconnDelay(uiDelay); pConn->close(); }
///分发channel的线程函数,arg为app对象 void* CwxMqApp::dispatchThreadMain(CwxTss* tss, CwxMsgQueue* queue, void* arg) { CwxMqApp* app = (CwxMqApp*) arg; if (0 != app->getDispChannel()->open()) { CWX_ERROR(("Failure to open dispatch channel")); return NULL; } while (1) { //获取队列中的消息并处理 if (0!= dealDispatchThreadQueueMsg(tss, queue, app, app->getDispChannel())) { break; } if (-1 == app->getDispChannel()->dispatch(1)) { CWX_ERROR(("Failure to CwxAppChannel::dispatch()")); sleep(1); } ///检查关闭的连接 CwxMqDispHandler::dealClosedSession(app, (CwxMqTss*) tss); } ///释放分发的资源 CwxMqDispHandler::destroy(app); app->getDispChannel()->stop(); app->getDispChannel()->close(); if (!app->isStopped()) { CWX_INFO(("Stop app for disptch channel thread stopped.")); app->stop(); } return NULL; }
///1:发现记录;0:没有发现;-1:错误 int CwxMqInnerDispHandler::syncSeekToBinlog(CwxMqTss* tss) { int iRet = 0; CwxBinlogMgrCursor* item; if (!m_syncSession->m_heap.pop(item)) return 0; m_syncSession->m_unReadyBinlogCursor.push_back(item); m_syncSession->m_pBinlogCursor = item; CWX_UINT32 uiDataLen = item->m_pCursor->getHeader().getLogLen(); ///准备data读取的buf char* szData = tss->getBuf(uiDataLen); ///读取data iRet = item->m_binlogMgr->fetch(item->m_pCursor, szData, uiDataLen); if (-1 == iRet) { ///读取失败 CwxCommon::snprintf(tss->m_szBuf2K, 2047, "Failure to fetch data, topic:%s, err:%s", item->m_strTopic.c_str(), item->m_pCursor->getErrMsg()); CWX_ERROR(("tss->m_szBuf2K")); return -1; } if (!tss->m_pReader->unpack(szData, uiDataLen, false, true)) { CWX_ERROR(("Can't unpack binlog, sid=%s", CwxCommon::toString(item->m_pCursor->getHeader().getSid(), tss->m_szBuf2K))); return 0; } ///获取CWX_MQ_D的key,此为真正的data tss->m_pBinlogData = tss->m_pReader->getKey(CWX_MQ_D); if (!tss->m_pBinlogData) { CWX_ERROR(("Can't find key[%s] in binlog, sid=%s", CWX_MQ_D, CwxCommon::toString(item->m_pCursor->getHeader().getSid(), tss->m_szBuf2K))); return 0; } return 1; }
///设置mq连接的属性 int CwxProProxyApp::setMqSockAttr(CWX_HANDLE handle, void* ) { if (0 != CwxSocket::setKeepalive(handle, true, CWX_APP_DEF_KEEPALIVE_IDLE, CWX_APP_DEF_KEEPALIVE_INTERNAL, CWX_APP_DEF_KEEPALIVE_COUNT)) { CWX_ERROR(("Failure to set mq keep-alive, errno=%d", errno)); return -1; } int flags= 1; if (setsockopt(handle, IPPROTO_TCP, TCP_NODELAY, (void *)&flags, sizeof(flags)) != 0) { CWX_ERROR(("Failure to set mq NODELAY, errno=%d",errno)); return -1; } struct linger ling= {0, 0}; if (setsockopt(handle, SOL_SOCKET, SO_LINGER, (void *)&ling, sizeof(ling)) != 0) { CWX_ERROR(("Failure to set mqLINGER, errno=%d",errno)); return -1; } return 0; }
///分发mq channel的线程函数,arg为app对象 void* CwxMqApp::mqFetchThreadMain(CwxTss*, CwxMsgQueue* queue, void* arg) { CwxMqApp* app = (CwxMqApp*) arg; if (0 != app->getMqChannel()->open()) { CWX_ERROR(("Failure to open queue channel")); return NULL; } while (1) { //获取队列中的消息并处理 if (0 != dealMqFetchThreadQueueMsg(queue, app, app->getMqChannel())) break; if (-1 == app->getMqChannel()->dispatch(1)) { CWX_ERROR(("Failure to invoke CwxAppChannel::dispatch()")); sleep(1); } } app->getMqChannel()->stop(); app->getMqChannel()->close(); if (!app->isStopped()) { CWX_INFO(("Stop app for queue channel thread stopped.")); app->stop(); } return NULL; }
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; }
///发送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; }
///-1:失败,否则返回添加数据的尺寸 int CwxMqInnerDispHandler::syncPackMultiBinLog(CwxPackageWriter* writer, CwxPackageWriter* writer_item, CwxKeyValueItem const* pData, CWX_UINT32& uiLen, char* szErr2K) { ///形成binlog发送的数据包 if (CWX_MQ_ERR_SUCCESS != CwxMqPoco::packSyncDataItem(writer_item, m_syncSession->m_pBinlogCursor->m_pCursor->getHeader().getSid(), m_syncSession->m_pBinlogCursor->m_strTopic.c_str(), m_syncSession->m_pBinlogCursor->m_pCursor->getHeader().getDatetime(), *pData, szErr2K)) { ///形成数据包失败 CWX_ERROR(("Failure to pack binlog package, err:%s", szErr2K)); return -1; } if (!writer->addKeyValue(CWX_MQ_M, writer_item->getMsg(), writer_item->getMsgSize(), true)) { ///形成数据包失败 CwxCommon::snprintf(szErr2K, 2047, "Failure to pack binlog package, err:%s", writer->getErrMsg()); CWX_ERROR((szErr2K)); return -1; } uiLen = CwxPackage::getKvLen(strlen(CWX_MQ_M), writer_item->getMsgSize()); return 1; }
int CwxAppFramework::noticeHandle4Event(CWX_UINT32 uiSvrId, CWX_UINT32 uiHostId, CWX_HANDLE handle, void* userData, CWX_UINT16 unEventMask, CWX_UINT32 uiMillSecond) { if (uiSvrId < SVR_TYPE_USER_START) { CWX_ERROR(("svr-id must not less than SVR_TYPE_USER_START")); return -1; } unEventMask &= CwxAppHandler4Base::RW_MASK; if (!unEventMask) { CWX_ERROR(("Not set handle's event mask, svr_id=%u, handle=%u", uiSvrId, (CWX_UINT32)handle)); return -1; } CwxAppHandler4IoEvent* pHandle = m_pHandleCache->fetchIoEventHandle(); if (!pHandle) pHandle = new CwxAppHandler4IoEvent(this, reactor()); pHandle->setHandle(handle); pHandle->setSvrId(uiSvrId); pHandle->setHostId(uiHostId); pHandle->setIoEventMask(unEventMask); pHandle->setUserData(userData); int ret = reactor()->registerHandler(handle, pHandle, unEventMask,CWX_APP_INVALID_CONN_ID, uiMillSecond); if (0 != ret) { pHandle->setHandle(CWX_INVALID_HANDLE); m_pHandleCache->cacheIoEventHandle(pHandle); CWX_ERROR(("Failure to register io handler to reactor")); return -1; } 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; }
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 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 CwxAppEpoll::resumeHandler (CWX_HANDLE handle, int resume_mask) { 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; } CwxAppHandler4Base* event_handler = m_eHandler[handle].m_handler; if (!event_handler) { CWX_ERROR(("Handler[%d] doesn't exist.", handle)); return -1; } resume_mask &=CwxAppHandler4Base::RW_MASK; resume_mask &=~m_eHandler[handle].m_mask; if(!resume_mask) return 0; if (0 != addEvent(handle, resume_mask)) { CWX_ERROR(("Failure to resume handler[%d]", handle)); return -1; } m_eHandler[handle].m_mask |=resume_mask; return 0; }
int CwxAppFramework::noticeLsockListen(CWX_UINT32 uiSvrId, char const* szPathFile, bool bRawData , CWX_UINT16 unMode, CWX_NET_SOCKET_ATTR_FUNC fn, void* fnArg) { if (uiSvrId < SVR_TYPE_USER_START) { CWX_ERROR(("svr-id must not less than SVR_TYPE_USER_START")); return -1; } CWX_UINT32 uiListenId = 0; CwxAppUnixAcceptor* acceptor=NULL; CwxUnixAddr unixAddr; uiListenId = m_pListenMgr->getNextListenId(); acceptor = new CwxAppUnixAcceptor(this, reactor(), szPathFile, uiSvrId, uiListenId, bRawData, unMode, fn, fnArg); unixAddr.set(szPathFile); CwxFile::rmFile(szPathFile); //register the acceptor if (acceptor->accept(unixAddr) != 0) { CWX_ERROR(("Can't open local unix listen for unix-file=%s, errno=%d", szPathFile, errno)); acceptor->close(); return -1; } if (0 != acceptor->open()) { CWX_ERROR(("Failure to register local unix listen for unix-file=%s", szPathFile)); acceptor->close(); return -1; } //create and init the notice object. CwxAppNotice* notice = new CwxAppNotice(); notice->m_unNoticeType = CwxAppNotice::UNIX_LISTEN; notice->m_noticeArg = acceptor; if (0 != m_pReactor->notice(notice)) { acceptor->close(); delete notice; CWX_ERROR(("Failure to notice local unix listen by PIPE")); return -1; } return (int)uiListenId; }
///设置slave dispatch连接的属性 int CwxMqApp::setDispatchSockAttr(CWX_HANDLE handle, void* arg) { CwxMqApp* app = (CwxMqApp*) arg; if (app->getConfig().getCommon().m_uiSockBufSize) { int iSockBuf = (app->getConfig().getCommon().m_uiSockBufSize + 1023) / 1024; iSockBuf *= 1024; while (setsockopt(handle, SOL_SOCKET, SO_SNDBUF, (void*) &iSockBuf, sizeof(iSockBuf)) < 0) { iSockBuf -= 1024; if (iSockBuf <= 1024) break; } iSockBuf = (app->getConfig().getCommon().m_uiSockBufSize + 1023) / 1024; iSockBuf *= 1024; while (setsockopt(handle, SOL_SOCKET, SO_RCVBUF, (void *) &iSockBuf, sizeof(iSockBuf)) < 0) { iSockBuf -= 1024; if (iSockBuf <= 1024) break; } } if (app->getConfig().getDispatch().m_async.isKeepAlive()) { if (0!= CwxSocket::setKeepalive(handle, true, CWX_APP_DEF_KEEPALIVE_IDLE, CWX_APP_DEF_KEEPALIVE_INTERNAL, CWX_APP_DEF_KEEPALIVE_COUNT)) { CWX_ERROR(("Failure to set listen addr:%s, port:%u to keep-alive, errno=%d", app->getConfig().getDispatch().m_async.getHostName().c_str(), app->getConfig().getDispatch().m_async.getPort(), errno)); return -1; } } int flags = 1; if (setsockopt(handle, IPPROTO_TCP, TCP_NODELAY, (void *) &flags, sizeof(flags)) != 0) { CWX_ERROR(("Failure to set listen addr:%s, port:%u NODELAY, errno=%d", app->getConfig().getDispatch().m_async.getHostName().c_str(), app->getConfig().getDispatch().m_async.getPort(), errno)); return -1; } struct linger ling = { 0, 0 }; if (setsockopt(handle, SOL_SOCKET, SO_LINGER, (void *) &ling, sizeof(ling)) != 0) { CWX_ERROR(("Failure to set listen addr:%s, port:%u LINGER, errno=%d", app->getConfig().getDispatch().m_async.getHostName().c_str(), app->getConfig().getDispatch().m_async.getPort(), errno)); return -1; } return 0; }
/** @brief 架构事件的循环处理API,实现消息的分发。 @return -1:失败;0:正常退出 */ int CwxAppReactor::run(REACTOR_EVENT_HOOK hook, void* arg, bool bOnce, CWX_UINT32 uiMiliTimeout) { int ret = 0; if (!bOnce) { if (!m_bStop || !m_engine) { CWX_ERROR(("CwxAppReactor::open() must be invoke before CwxAppReactor::run()")); return -1; } } m_bStop = false; do { { ///带锁执行event-loop CwxMutexGuard<CwxMutexLock> lock(&m_lock); ret = m_engine->poll(CwxAppReactor::callback, this, uiMiliTimeout); } if (m_bStop) { CWX_DEBUG(("Stop running for stop")); break; } if (0 != ret) { if ((-1 == ret) && (EINTR != errno)) { CWX_ERROR(("Failure to running epoll with -1, errno=%d", errno)); break; } } ///调用hook if (hook) { if (0 != hook(arg)) { CWX_DEBUG(("Stop running for hook() without 0")); break; } } ///等待其他的线程执行各种操作。 m_rwLock.acquire_write(); m_rwLock.release(); } while(!m_bStop && !bOnce); return ret; }
///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; } }
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; }
void CwxEchoChannelEventHandler::replyMessage() { ///设置echo回复的消息类型,为请求的消息类型+1 m_recvMsgData->event().getMsgHeader().setMsgType(m_recvMsgData->event().getMsgHeader().getMsgType() + 1); ///设置echo回复的数据包长度 m_recvMsgData->event().getMsgHeader().setDataLen(m_recvMsgData->length()); ///创建回复的数据包 CwxMsgBlock* pBlock = CwxMsgBlockAlloc::malloc(m_recvMsgData->length() + CwxMsgHead::MSG_HEAD_LEN); ///拷贝数据包的包头 memcpy(pBlock->wr_ptr(), m_recvMsgData->event().getMsgHeader().toNet(), CwxMsgHead::MSG_HEAD_LEN); ///滑动block的写指针 pBlock->wr_ptr(CwxMsgHead::MSG_HEAD_LEN); ///拷贝数据包的数据 memcpy(pBlock->wr_ptr(), m_recvMsgData->rd_ptr(), m_recvMsgData->length()); ///滑动block的写指针 pBlock->wr_ptr(m_recvMsgData->length()); if (!putMsg(pBlock)) { CWX_ERROR(("Failure to put message")); CwxMsgBlockAlloc::free(pBlock); } 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)); } }
///fork的re-init方法,返回值,0:成功;-1:失败 int CwxAppReactor::forkReinit() { if (m_engine) { m_owner = CwxThread::self(); int ret = m_engine->forkReinit(); if (-1 == ret) { CWX_ERROR(("Failure to invoke libevent::event_reinit")); return -1; } return 0; } CWX_ERROR(("Epoll engine doesn't init")); return -1; }
///用户自定义事件处理函数 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; }
void CwxAppFramework::onTime(CwxTimeValue const& current) { CWX_UNUSED_ARG(current); if (isStopped()) return; static time_t lastLogTime=0; if (time(NULL) - lastLogTime > getLogCheckSecond()) {//check log if (CwxLogger::instance()->getLogFileSize() > (int)this->getLogFileSize()) { CwxLogger::instance()->nextLog(false); } lastLogTime = time(NULL); } static time_t ttLastStateCheck = time(NULL); if (time(NULL) - ttLastStateCheck > 1) { ttLastStateCheck = time(NULL); CwxTss::instance()->getThreadInfo().setUpdateTime(ttLastStateCheck); if (APP_MODE_ALONE != m_unAppMode) { if (1 == ::getppid()) { CWX_ERROR(("Parent proccess is stopped, existing...")); this->stop(); } } if (APP_MODE_TWIN == m_unAppMode) { kill(::getppid(), SIGHUP); } } }
int CwxAppFramework::noticeTcpConnect(CWX_UINT32 uiSvrId, CWX_UINT32 uiHostId, char const* szAddr, CWX_UINT16 unPort, bool bRawData, CWX_UINT16 unMinRetryInternal, CWX_UINT16 unMaxRetryInternal, CWX_NET_SOCKET_ATTR_FUNC fn, void* fnArg, CWX_UINT32 uiMiliTimeout, CWX_INT32 iFamily) { if (uiSvrId < SVR_TYPE_USER_START) { CWX_ERROR(("svr-id must not less than SVR_TYPE_USER_START")); return -1; } CwxAppHandler4TcpConn* handle = m_pHandleCache->fetchTcpHandle(); if (!handle) handle = new CwxAppHandler4TcpConn(this, reactor()); CWX_UINT32 uiConnId = m_pReactor->getNextConnId(); handle->getConnInfo().setSvrId(uiSvrId); handle->getConnInfo().setHostId(uiHostId); handle->setConnectAddr(szAddr); handle->setConnectPort(unPort); handle->getConnInfo().setRawData(bRawData); handle->getConnInfo().setMinRetryInternal(unMinRetryInternal); handle->getConnInfo().setMaxRetryInternal(unMaxRetryInternal); handle->getConnInfo().setConnId(uiConnId); handle->getConnInfo().setActiveConn(true); handle->getConnInfo().setSockFunc(fn); handle->getConnInfo().setSockFuncArg(fnArg); handle->getConnInfo().setConnectTimeout(uiMiliTimeout); handle->getConnInfo().setFamily(iFamily); CwxAppNotice* notice = new CwxAppNotice(); notice->m_unNoticeType = CwxAppNotice::TCP_CONNECT; notice->m_noticeArg = handle; if (0 != m_pReactor->notice(notice)) { delete handle; delete notice; CWX_ERROR(("Failure to notice tcp connection")); return -1; } return (int)uiConnId; }
///唤醒连接的可写监控,以发送未发送完毕的数据.返回值, -1:failure; 0:success。 int CwxAppHandler4Channel::wakeUp() { if(-1 == channel()->resumeHandler(this, CwxAppHandler4Base::WRITE_MASK)){ CWX_ERROR(("Failure to wakeup a connection. conn[%d]", getHandle())); return -1; } return 0; }
///由于没有消息发送,使连接的发送监测休眠.返回值, -1: failure, 0: success int CwxAppHandler4Channel::cancelWakeup() { if(-1 == channel()->suspendHandler(this, CwxAppHandler4Base::WRITE_MASK)){ CWX_ERROR(("Failure to cancel wakeup a connection. conn[%d]", getHandle())); return -1; } return 0; }
int CwxAppFramework::noticeSuspendConn(CWX_UINT32 uiConnId){ if (!m_pReactor->suspendHandlerByConnId(uiConnId, CwxAppHandler4Base::READ_MASK)) { CWX_ERROR(("Failure to suspend conn[%u]", uiConnId)); return -1; } return 0; }
int CwxAppFramework::noticeSuspendListen(CWX_UINT32 uiListenId){ if (!m_pListenMgr->suspend(uiListenId)) { CWX_ERROR(("Failure to suspend listen")); return -1; } return 0; }
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; }
int CwxAppFramework::noticeResumeListen(CWX_UINT32 uiListenId) { if (!m_pListenMgr->resume(uiListenId)) { CWX_ERROR(("Failure to resume listen")); return -1; } return 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; }