// PD_TRACE_DECLARE_FUNCTION ( SDB__MIGLOADJSONPS__CHECKWORKER, "migMaster::_checkErrAndRollback" ) INT32 migMaster::_checkErrAndRollback ( pmdEDUCB *eduCB, dmsStorageLoadOp* loadOp, dmsMBContext *mbContext, UINT32 &success, UINT32 &failure ) { INT32 rc = SDB_OK ; PD_TRACE_ENTRY ( SDB__MIGLOADJSONPS__CHECKWORKER ); pmdEDUEvent event ; /*isGetEven = eduCB->waitEvent ( event, 0 ) ; if ( isGetEven ) { workerRe = (_workerReturn *)event._Data ; success += workerRe->success ; failure += workerRe->failure ; --_workerNum ; }*/ if ( !_exitSignal ) { _exitSignal = !_sock->isConnected() ; if ( !_exitSignal ) { _exitSignal = eduCB->isForced() ; } } if ( _exitSignal ) { PD_LOG ( PDERROR, "rollback all data" ) ; sendMsgToClient ( "Error: rollback all data" ) ; rc = _stopAndWaitWorker ( eduCB, success, failure ) ; PD_RC_CHECK ( rc, PDERROR, "Failed to call _stopAndWaitWorker, rc=%d", rc ) ; rc = loadOp->loadRollbackPhase ( mbContext ) ; if ( rc ) { PD_LOG ( PDERROR, "Failed to rollback, rc=%d", rc ) ; sendMsgToClient ( "Error: Failed to rollback, rc = %d", rc ) ; goto error ; } rc = SDB_LOAD_ROLLBACK ; goto error ; } done: PD_TRACE_EXITRC ( SDB__MIGLOADJSONPS__CHECKWORKER, rc ); return rc ; error: goto done ; }
// 收到内部服务发往网络客户端的消息 int CSrvMsgHandler::onServiceMessage(const char* msgData, const unsigned int msgLen, const char* userData, const unsigned int userDataLen, unsigned short dstProtocolId, unsigned int srcSrvId, unsigned short srcSrvType, unsigned short srcModuleId, unsigned short srcProtocolId, int userFlag, unsigned int msgId, const char* srvAsyncDataFlag, unsigned int srvAsyncDataFlagLen) { if (dstProtocolId >= MaxProtocolIDCount) { OptErrorLog("receive error service msg, srcServiceId = %d, srcServiceType = %d, dstProtocolId = %d", srcSrvId, srcSrvType, dstProtocolId); return InvalidParam; } // 服务要求停止连接代理 if (srcProtocolId == ConnectProxyOperation::StopProxy) return stopServiceConnect(srcSrvId); IndexToConnects::iterator it = m_idx2Connects.find(userFlag); if (it == m_idx2Connects.end()) { int rc = sendMessage(NULL, 0, userFlag, NULL, 0, srcSrvId, 0, 0, ConnectProxyOperation::PassiveClosed, 0); // 通知服务,对应的连接已经被关闭了 OptErrorLog("can not find the connect proxy data, srcServiceId = %d, srcServiceType = %d, dstProtocolId = %d, userFlag = %d, rc = %d", srcSrvId, srcSrvType, dstProtocolId, userFlag, rc); return InvalidParam; } if (srcProtocolId != ConnectProxyOperation::ActiveClosed) { // 服务消息转发给网络客户端 if (srcSrvType == ServiceType::GameHallSrv) srcSrvId = m_gameHallId; // 游戏大厅 sendMsgToClient(msgData, msgLen, dstProtocolId, it->second.conn, srcSrvId, srcModuleId, msgId); } else { // 这里不可以调用 resetUserData(it->second.conn, NULL) 屏蔽回调; 之后接着调用 closeConnect(it->second.conn),然后删除连接数据 // 实际上存在客户端和这里同时关闭连接的情况,因此可能在 resetUserData 之前,连接挂接的数据已经被连接线程放入队列里了 // 这样的话会导致连接关闭函数 onClosedConnect 被回调时传递的参数是无效的,访问无效参数则直接崩溃 it->second.serviceId2ConnectIdx.erase(srcSrvId); // 连接被服务主动关闭了 OptWarnLog("to do active close connect, srcSrvId = %d, userFlag = %d, ip = %s, port = %d, isEmpty = %d, index = %d", srcSrvId, userFlag, CSocket::toIPStr(it->second.conn->peerIp), it->second.conn->peerPort, it->second.serviceId2ConnectIdx.empty(), it->second.index); if (it->second.serviceId2ConnectIdx.empty()) closeConnect(it->second.conn); // 该连接没有服务对应了,则关闭连接 } return Success; }
// PD_TRACE_DECLARE_FUNCTION ( SDB__MIGLOADJSONPS__RUN, "migMaster::run" ) INT32 migMaster::run() { INT32 rc = SDB_OK ; PD_TRACE_ENTRY ( SDB__MIGLOADJSONPS__RUN ); UINT32 startOffset = 0 ; UINT32 size = 0 ; UINT32 startBlock = 0 ; UINT32 endBlock = 0 ; pmdKRCB *krcb = pmdGetKRCB () ; pmdEDUMgr *eduMgr = krcb->getEDUMgr () ; SDB_DMSCB *dmsCB = krcb->getDMSCB () ; pmdEDUCB *eduCB = eduMgr->getEDU() ; EDUID agentEDU = PMD_INVALID_EDUID ; BOOLEAN writable = FALSE ; BOOLEAN noClearFlag = FALSE ; dmsMBContext *mbContext = NULL ; UINT32 line = 0 ; UINT32 column = 0 ; UINT32 success = 0 ; UINT32 failure = 0 ; UINT16 clFlag = 0 ; dmsStorageUnitID suID = DMS_INVALID_CS ; dmsStorageUnit *su = NULL ; initWorker dataWorker ; pmdEDUEvent event ; dmsStorageLoadOp dmsLoadExtent ; sendMsgToClient ( "Load start" ) ; rc = rtnCollectionSpaceLock ( _pParameters->pCollectionSpaceName, dmsCB, FALSE, &su, suID ) ; if ( rc ) { if ( SDB_DMS_CS_NOTEXIST == rc ) { sendMsgToClient ( "Error: collection space not exist" ) ; } PD_LOG ( PDERROR, "Failed to lock collection space, rc=%d", rc ) ; goto error ; } dmsLoadExtent.init ( su ) ; rc = su->data()->getMBContext( &mbContext, _pParameters->pCollectionName, EXCLUSIVE ) ; if ( rc ) { if ( SDB_DMS_NOTEXIST == rc ) { sendMsgToClient ( "Error: collection not exist" ) ; } PD_LOG ( PDERROR, "Failed to lock collection, rc=%d", rc ) ; goto error ; } clFlag = mbContext->mb()->_flag ; if ( DMS_IS_MB_DROPPED( clFlag ) ) { PD_LOG( PDERROR, "Collection is droped" ) ; rc = SDB_COLLECTION_LOAD ; sendMsgToClient ( "Collection is droped" ) ; goto error ; } else if ( DMS_IS_MB_LOAD ( clFlag ) ) { PD_LOG( PDERROR, "Collection is loading" ) ; rc = SDB_COLLECTION_LOAD ; sendMsgToClient ( "Collection is loading" ) ; // we set noClearFlag to true, so that we'll convert the collection // flag to NORMAL in done noClearFlag = TRUE ; goto error ; } dmsLoadExtent.setFlagLoad ( mbContext->mb() ) ; dmsLoadExtent.setFlagLoadLoad ( mbContext->mb() ) ; // unlock mbContext->mbUnlock() ; rc = dmsCB->writable( eduCB ) ; if ( rc ) { PD_LOG ( PDERROR, "Database is not writable, rc = %d", rc ) ; goto error; } writable = TRUE; dataWorker.pMaster = this ; dataWorker.masterEDUID = eduCB->getID() ; dataWorker.pSu = su ; dataWorker.clLID = mbContext->clLID() ; dataWorker.collectionID = mbContext->mbID() ; for ( UINT32 i = 0; i < _pParameters->workerNum; ++i ) { eduMgr->startEDU ( EDU_TYPE_LOADWORKER, &dataWorker, &agentEDU ) ; } while ( TRUE ) { rc = _checkErrAndRollback ( eduCB, &dmsLoadExtent, mbContext, success, failure ) ; if ( SDB_TIMEOUT != rc && rc ) { PD_LOG ( PDERROR, "Failed to call _checkErrAndRollback, rc=%d", rc ) ; goto error ; } // fetch one record rc = _parser->getNextRecord ( startOffset, size, &line, &column, _ppBucket ) ; if ( rc ) { // special handle for end of file if ( rc == SDB_EOF ) { // when we hit end of file, let's push 0 to all worker threads, // with num of workers ( so each worker will dispatch one 0, and // exit ) rc = _stopAndWaitWorker ( eduCB, success, failure ) ; PD_RC_CHECK ( rc, PDERROR, "Failed to call _stopAndWaitWorker, rc=%d", rc ) ; break ; } sendMsgToClient ( "Error: Parse Json error in line: %u," " column: %u", line, column ) ; PD_LOG ( PDERROR, "Failed to parseJSONs getNextRecord,rc=%d", rc ) ; goto error1 ; } // calculate the blocks to be locked, based on the length of our record rc = getBlockFromPointer ( startOffset, size, startBlock, endBlock ) ; if ( rc ) { PD_LOG ( PDERROR, "Failed to get block from pointer, rc=%d", rc ) ; goto error1 ; } // lock them for ( UINT32 i = startBlock; i <= endBlock; ++i ) { _ppBucket[i]->inc() ; } // push the record to queue pushToQueue ( startOffset, size, line, column ) ; } // while ( !eduCB->isForced() ) // when all workers are finish, let's start build phase to rebuild all // indexes sendMsgToClient ( "build index" ) ; rc = dmsLoadExtent.loadBuildPhase ( mbContext, eduCB, _pParameters->isAsynchronous, this, &success, &failure ) ; if ( rc ) { PD_LOG ( PDERROR, "Failed to load data, rc=%d", rc ) ; goto error ; } done: // we only lock and clear flag if we switched to load if ( su && mbContext && !noClearFlag ) { rc = mbContext->mbLock( EXCLUSIVE ) ; // we should log failure information if ( SDB_OK == rc ) { if ( dmsLoadExtent.isFlagLoadLoad ( mbContext->mb() ) ) { dmsLoadExtent.clearFlagLoadLoad ( mbContext->mb() ) ; } if ( dmsLoadExtent.isFlagLoadBuild ( mbContext->mb() ) ) { dmsLoadExtent.clearFlagLoadBuild ( mbContext->mb() ) ; } if ( dmsLoadExtent.isFlagLoad ( mbContext->mb() ) ) { dmsLoadExtent.clearFlagLoad ( mbContext->mb() ) ; } } else { PD_LOG ( PDERROR, "Failed to lock collection, rc=%d", rc ) ; } } // send the success message to client sendMsgToClient ( "success json: %u, failure json: %u", success, failure ) ; sendMsgToClient ( "Load end" ) ; if ( su && mbContext ) { su->data()->releaseMBContext( mbContext ) ; } if ( DMS_INVALID_CS != suID ) { dmsCB->suUnlock ( suID ) ; } // count down if ( writable ) { dmsCB->writeDown( eduCB ); } PD_TRACE_EXITRC ( SDB__MIGLOADJSONPS__RUN, rc ); return rc ; error: goto done ; error1: _stopAndWaitWorker ( eduCB, success, failure ) ; sendMsgToClient ( "Error: rollback all data" ) ; failure += success ; success = 0 ; rc = dmsLoadExtent.loadRollbackPhase ( mbContext ) ; if ( rc ) { PD_LOG ( PDERROR, "Failed to rollback, rc=%d", rc ) ; sendMsgToClient ( "Error: Failed to rollback, rc = %d", rc ) ; goto error ; } goto done ; }
INT32 migMaster::_checkErrAndRollback ( pmdEDUCB *eduCB, dmsStorageLoadOp* loadOp, dmsMBContext *mbContext, UINT32 &success, UINT32 &failure ) { INT32 rc = SDB_OK ; PD_TRACE_ENTRY ( SDB__MIGLOADJSONPS__CHECKWORKER ); pmdEDUEvent event ; // if we receive any post, that means worker got something wrong and we // should handle it respectively /*isGetEven = eduCB->waitEvent ( event, 0 ) ; if ( isGetEven ) { // if we receive anything, let's count the success and failure and // goon, note it means something wrong happened at worker workerRe = (_workerReturn *)event._Data ; success += workerRe->success ; failure += workerRe->failure ; --_workerNum ; }*/ // if something wrong happened at worker, or the connection is gone, // let's rollback //if ( isGetEven || !_sock->isConnected() ) if ( !_exitSignal ) { _exitSignal = !_sock->isConnected() ; if ( !_exitSignal ) { _exitSignal = eduCB->isForced() ; } } if ( _exitSignal ) { // print the error in log PD_LOG ( PDERROR, "rollback all data" ) ; // send error to user side, note we don't need to check rc since we // can't do anything if it's not success, anyway sendMsgToClient ( "Error: rollback all data" ) ; rc = _stopAndWaitWorker ( eduCB, success, failure ) ; PD_RC_CHECK ( rc, PDERROR, "Failed to call _stopAndWaitWorker, rc=%d", rc ) ; //roll back rc = loadOp->loadRollbackPhase ( mbContext ) ; if ( rc ) { PD_LOG ( PDERROR, "Failed to rollback, rc=%d", rc ) ; sendMsgToClient ( "Error: Failed to rollback, rc = %d", rc ) ; goto error ; } rc = SDB_LOAD_ROLLBACK ; goto error ; } done: PD_TRACE_EXITRC ( SDB__MIGLOADJSONPS__CHECKWORKER, rc ); return rc ; error: goto done ; }
INT32 migMaster::initialize ( setParameters *pParameters ) { INT32 rc = SDB_OK ; PD_TRACE_ENTRY ( SDB__MIGLOADJSONPS__INITIALIZE ); _utilParserParamet parserPara ; UINT32 startOffset = 0 ; UINT32 fieldsSize = 0 ; _pParameters = pParameters ; _sock = _pParameters->clientSock ; _fileType = _pParameters->fileType ; _blockSize = _pParameters->bufferSize/_pParameters->bucketNum ; _exitSignal = FALSE ; if ( MIG_PARSER_JSON == _pParameters->fileType ) { _parser = SDB_OSS_NEW _utilJSONParser() ; } else if ( MIG_PARSER_CSV == _pParameters->fileType ) { _parser = SDB_OSS_NEW _utilCSVParser() ; } else { rc = SDB_MIG_UNKNOW_FILE_TYPE ; PD_LOG ( PDERROR, "Unknow file type" ) ; goto error ; } PD_CHECK ( _parser, SDB_OOM, error, PDERROR, "Failed to new _parser" ) ; _ppBucket = (_bucket**)SDB_OSS_MALLOC ( sizeof(_bucket*) * _pParameters->bucketNum ) ; PD_CHECK ( _ppBucket, SDB_OOM, error, PDERROR, "Failed to allocate bucket pointer array" ) ; ossMemset ( _ppBucket, 0, sizeof(_bucket*) * _pParameters->bucketNum ) ; for ( UINT32 i = 0; i < _pParameters->bucketNum; ++i ) { _ppBucket[i] = SDB_OSS_NEW _bucket() ; PD_CHECK ( _ppBucket[i], SDB_OOM, error, PDERROR, "Failed to allocate bucket pointer array" ) ; } _parser->setDel ( _pParameters->delCFR[0], _pParameters->delCFR[1], _pParameters->delCFR[2] ) ; parserPara.fileName = _pParameters->pFileName ; parserPara.bufferSize = _pParameters->bufferSize ; parserPara.blockNum = _pParameters->bucketNum ; rc = _parser->initialize( &parserPara ) ; if ( rc ) { PD_LOG ( PDERROR, "Failed to init utilParseJSONs, rc = %d", rc ) ; if ( SDB_IO == rc || SDB_FNE == rc ) { sendMsgToClient ( "Failed to open file %s, rc=%d", _pParameters->pFileName, rc ) ; } goto error ; } _buffer = _parser->getBuffer() ; _delChar = _pParameters->delCFR[0] ; _delField = _pParameters->delCFR[1] ; _delRecord = _pParameters->delCFR[2] ; _autoAddField = TRUE ; _autoCompletion = FALSE ; _isHeaderline = _pParameters->headerline ; if ( _isHeaderline ) { rc = _parser->getNextRecord ( startOffset, fieldsSize ) ; if ( rc ) { if ( rc == SDB_EOF ) { if ( 0 == fieldsSize ) { goto done ; } } else { PD_LOG ( PDERROR, "Failed to _parser getNextRecord, rc=%d", rc ) ; goto error ; } } } if ( _pParameters->pFieldArray ) { _pFields = _pParameters->pFieldArray ; _fieldsSize = ossStrlen( _pFields ) ; } else { _pFields = _buffer + startOffset ; _fieldsSize = fieldsSize ; } done: PD_TRACE_EXITRC ( SDB__MIGLOADJSONPS__INITIALIZE, rc ); return rc ; error: goto done ; }
// PD_TRACE_DECLARE_FUNCTION ( SDB__MIGLOADJSONPS__RUN, "migMaster::run" ) INT32 migMaster::run( pmdEDUCB *cb ) { INT32 rc = SDB_OK ; PD_TRACE_ENTRY ( SDB__MIGLOADJSONPS__RUN ); UINT32 startOffset = 0 ; UINT32 size = 0 ; UINT32 startBlock = 0 ; UINT32 endBlock = 0 ; pmdKRCB *krcb = pmdGetKRCB () ; pmdEDUMgr *eduMgr = krcb->getEDUMgr () ; SDB_DMSCB *dmsCB = krcb->getDMSCB () ; EDUID agentEDU = PMD_INVALID_EDUID ; BOOLEAN writable = FALSE ; BOOLEAN noClearFlag = FALSE ; dmsMBContext *mbContext = NULL ; UINT32 line = 0 ; UINT32 column = 0 ; UINT32 success = 0 ; UINT32 failure = 0 ; UINT16 clFlag = 0 ; dmsStorageUnitID suID = DMS_INVALID_CS ; dmsStorageUnit *su = NULL ; initWorker dataWorker ; pmdEDUEvent event ; dmsStorageLoadOp dmsLoadExtent ; sendMsgToClient ( "Load start" ) ; rc = dmsCB->writable( cb ) ; if ( rc ) { PD_LOG ( PDERROR, "Database is not writable, rc = %d", rc ) ; goto error; } writable = TRUE; rc = rtnCollectionSpaceLock ( _pParameters->pCollectionSpaceName, dmsCB, FALSE, &su, suID ) ; if ( rc ) { if ( SDB_DMS_CS_NOTEXIST == rc ) { sendMsgToClient ( "Error: collection space not exist" ) ; } PD_LOG ( PDERROR, "Failed to lock collection space, rc=%d", rc ) ; goto error ; } dmsLoadExtent.init ( su ) ; rc = su->data()->getMBContext( &mbContext, _pParameters->pCollectionName, EXCLUSIVE ) ; if ( rc ) { if ( SDB_DMS_NOTEXIST == rc ) { sendMsgToClient ( "Error: collection not exist" ) ; } PD_LOG ( PDERROR, "Failed to lock collection, rc=%d", rc ) ; goto error ; } clFlag = mbContext->mb()->_flag ; if ( DMS_IS_MB_DROPPED( clFlag ) ) { PD_LOG( PDERROR, "Collection is droped" ) ; rc = SDB_COLLECTION_LOAD ; sendMsgToClient ( "Collection is droped" ) ; goto error ; } else if ( DMS_IS_MB_LOAD ( clFlag ) ) { PD_LOG( PDERROR, "Collection is loading" ) ; rc = SDB_COLLECTION_LOAD ; sendMsgToClient ( "Collection is loading" ) ; noClearFlag = TRUE ; goto error ; } dmsLoadExtent.setFlagLoad ( mbContext->mb() ) ; dmsLoadExtent.setFlagLoadLoad ( mbContext->mb() ) ; mbContext->mbUnlock() ; dataWorker.pMaster = this ; dataWorker.masterEDUID = cb->getID() ; dataWorker.pSu = su ; dataWorker.clLID = mbContext->clLID() ; dataWorker.collectionID = mbContext->mbID() ; for ( UINT32 i = 0; i < _pParameters->workerNum ; ++i ) { eduMgr->startEDU ( EDU_TYPE_LOADWORKER, &dataWorker, &agentEDU ) ; } while ( TRUE ) { rc = _checkErrAndRollback ( cb, &dmsLoadExtent, mbContext, success, failure ) ; if ( SDB_TIMEOUT != rc && rc ) { PD_LOG ( PDERROR, "Failed to call _checkErrAndRollback, rc=%d", rc ) ; goto error ; } rc = _parser->getNextRecord ( startOffset, size, &line, &column, _ppBucket ) ; if ( rc ) { if ( rc == SDB_EOF ) { rc = _stopAndWaitWorker ( cb, success, failure ) ; PD_RC_CHECK ( rc, PDERROR, "Failed to call _stopAndWaitWorker, rc=%d", rc ) ; break ; } sendMsgToClient ( "Error: Parse Json error in line: %u," " column: %u", line, column ) ; PD_LOG ( PDERROR, "Failed to parseJSONs getNextRecord,rc=%d", rc ) ; goto error1 ; } rc = getBlockFromPointer ( startOffset, size, startBlock, endBlock ) ; if ( rc ) { PD_LOG ( PDERROR, "Failed to get block from pointer, rc=%d", rc ) ; goto error1 ; } for ( UINT32 i = startBlock; i <= endBlock; ++i ) { _ppBucket[i]->inc() ; } pushToQueue ( startOffset, size, line, column ) ; } // while ( !cb->isForced() ) sendMsgToClient ( "build index" ) ; rc = dmsLoadExtent.loadBuildPhase ( mbContext, cb, _pParameters->isAsynchronous, this, &success, &failure ) ; if ( rc ) { PD_LOG ( PDERROR, "Failed to load data, rc=%d", rc ) ; goto error ; } done: if ( su && mbContext && !noClearFlag ) { rc = mbContext->mbLock( EXCLUSIVE ) ; if ( SDB_OK == rc ) { if ( dmsLoadExtent.isFlagLoadLoad ( mbContext->mb() ) ) { dmsLoadExtent.clearFlagLoadLoad ( mbContext->mb() ) ; } if ( dmsLoadExtent.isFlagLoadBuild ( mbContext->mb() ) ) { dmsLoadExtent.clearFlagLoadBuild ( mbContext->mb() ) ; } if ( dmsLoadExtent.isFlagLoad ( mbContext->mb() ) ) { dmsLoadExtent.clearFlagLoad ( mbContext->mb() ) ; } } else { PD_LOG ( PDERROR, "Failed to lock collection, rc=%d", rc ) ; } } sendMsgToClient ( "success json: %u, failure json: %u", success, failure ) ; sendMsgToClient ( "Load end" ) ; if ( su && mbContext ) { su->data()->releaseMBContext( mbContext ) ; } if ( DMS_INVALID_CS != suID ) { dmsCB->suUnlock ( suID ) ; } if ( writable ) { dmsCB->writeDown( cb ); } PD_TRACE_EXITRC ( SDB__MIGLOADJSONPS__RUN, rc ); return rc ; error: goto done ; error1: _stopAndWaitWorker ( cb, success, failure ) ; sendMsgToClient ( "Error: rollback all data" ) ; failure += success ; success = 0 ; rc = dmsLoadExtent.loadRollbackPhase ( mbContext ) ; if ( rc ) { PD_LOG ( PDERROR, "Failed to rollback, rc=%d", rc ) ; sendMsgToClient ( "Error: Failed to rollback, rc = %d", rc ) ; goto error ; } goto done ; }