/** * Start message service in listening thread * TODO: Start a new background thread to receive message */ bool UNetworkManager::StartMessageService(FSocket* ClientSocket, const FIPv4Endpoint& ClientEndpoint) { if (!this->ConnectionSocket) { ConnectionSocket = ClientSocket; UE_LOG(LogUnrealCV, Warning, TEXT("New client connected from %s"), *ClientEndpoint.ToString()); // ClientSocket->SetNonBlocking(false); // When this in blocking state, I can not use this socket to send message back FString Confirm = FString::Printf(TEXT("connected to %s"), *GetProjectName()); bool IsSent = this->SendMessage(Confirm); // Send a hello message if (!IsSent) { UE_LOG(LogUnrealCV, Error, TEXT("Failed to send welcome message to client.")); } // TODO: Start a new thread while (this->ConnectionSocket) // Listening thread, while the client is still connected { FArrayReader ArrayReader; bool unknown_error = false; if (!FSocketMessageHeader::ReceivePayload(ArrayReader, ConnectionSocket, &unknown_error)) // Wait forever until got a message, or return false when error happened { if (unknown_error) { BroadcastError(FString("ReceivePayload failed with unknown error")); } this->ConnectionSocket = NULL; return false; // false will release the ClientSocket break; // Remote socket disconnected } FString Message = StringFromBinaryArray(ArrayReader); BroadcastReceived(Message); // Fire raw message received event, use message id to connect request and response UE_LOG(LogUnrealCV, Warning, TEXT("Receive message %s"), *Message); } return false; // TODO: What is the meaning of return value? } else { // No response and let the client silently timeout UE_LOG(LogUnrealCV, Warning, TEXT("Only one client is allowed, can not allow new connection from %s"), *ClientEndpoint.ToString()); return false; // Already have a connection } }
DWORD CPublisher::StoreInDatabase(CTrade& Trade) { USES_CONVERSION; DWORD dwTries = MAX_DBRECONNECTION_TRIES; bool bOk = false; DWORD dwRes = ERROR_SUCCESS; long lMaxSeqNum; long lMinSeqNum; long lStructureMissed; TDBFailsStore::iterator it; do { try { switch(Trade.siStatus) { case NEW_FLAG: case UPD_FLAG: { CClientRecordset rs; CStoredProc<> sp(m_ConnectionDest, L"usp_TradeFeed_1_New"); sp << Trade.vcAcronym; sp << _bstr_t(_variant_t((long)Trade.nTradeID)); sp << (int)( Trade.vcAction == ACTION_BUY ? 1 : 0 ); sp << (int)Trade.fUnits; sp << Trade.fPrice; sp << Trade.dtTradeDate; sp << Trade.vcSymbol; sp << int(0); // Contract Type s Stock sp << CDBNull(); sp << CDBNull(); sp << CDBNull(); sp << CDBNull(); sp << CDBNull(); sp << (int)1; //update enabled sp << CDBNull(); rs.Open (sp); if (rs.IsEOF()) { rs.Close(); _com_issue_error(E_FAIL); } lMaxSeqNum = rs[L"iMaxSeqNum"]; lMinSeqNum = rs[L"iMinSeqNum"]; lStructureMissed = rs[L"iStructureMissed"]; rs.Close(); if ( lMaxSeqNum == -1 && lStructureMissed == -1 ) { if (lMinSeqNum == -1) // unknown error { _com_issue_error( E_FAIL ); } else { dwRes = ERROR_ALREADY_EXISTS; if ( ReProcessTrade(Trade, lMinSeqNum) == ERROR_SUCCESS ) dwRes = ERROR_SUCCESS; break; } } CTracer::Trace(CTracer::enMtInformation, _T("Trade '%d' stored in database."), Trade.nTradeID); InterlockedIncrement((LPLONG)&m_dwDBStored); CStoredProc<> sp_get(m_ConnectionDest, L"usp_TradeSeq_Get"); sp_get << (int)lMinSeqNum; sp_get << (int)lMaxSeqNum; sp_get << CDBNull(); sp_get << (UCHAR)1; rs.Open (sp_get); if(rs.IsEOF()) { CTracer::Trace(CTracer::enMtError, _T("Failed to retrieve trade from database - trade with ExecID '%d' does not exist."), Trade.nTradeID); dwRes = ERROR_NO_DATA_DETECTED; } else { HRESULT hRes; while (!rs.IsEOF() && GetMode() == MODE_INTRADAY) { if ( FAILED(hRes = FillTradeUpdate(rs, Trade)) ) { CTracer::Trace(CTracer::enMtError, _T("Failed to fill TradeUpdate message.")); dwRes = ERROR_INVALID_PARAMETER; } else if(hRes == S_FALSE) { CTracer::Trace(CTracer::enMtError, _T("Failed to retrieve trade from database - trade with ExecID '%d' does not exist."), Trade.nTradeID); dwRes = ERROR_NO_DATA_DETECTED; } Publish(Trade); if (::WaitForSingleObject(GetStopEventHandle(), CSettings::m_nPublishDelayTime) == WAIT_OBJECT_0) { return _ERROR_NEED_TO_STOP; } rs.MoveNext(); } } } break; case DEL_FLAG: { CClientRecordset rs; CStoredProc<> sp(m_ConnectionDest, L"usp_TradeFeed_1_Del"); sp << _bstr_t(_variant_t((long)Trade.nTradeID)); sp << Trade.dtTradeDate; rs.Open (sp); if(rs.IsEOF()) { rs.Close(); _com_issue_error(E_FAIL); } lMaxSeqNum = rs[L"iMaxSeqNum"]; lMinSeqNum = rs[L"iMinSeqNum"]; rs.Close(); if (lMaxSeqNum == -1 && lMinSeqNum == -1) // unknown error _com_issue_error(E_FAIL); if (lMinSeqNum == -1) // already exists { dwRes = ERROR_ALREADY_EXISTS; if ( ReProcessTrade(Trade, lMaxSeqNum) == ERROR_SUCCESS ) dwRes = ERROR_SUCCESS; break; } if (lMaxSeqNum == -1) { CTracer::Trace(CTracer::enMtWarning, _T("Failed to delete trade in database - trade with the same ExecID '%d' either does not exist or was already deleted."), Trade.nTradeID); dwRes = ERROR_NOT_FOUND; break; } CTracer::Trace(CTracer::enMtInformation, _T("Trade '%d' deleted from database."), Trade.nTradeID); InterlockedIncrement((LPLONG)&m_dwDBDeleted); CStoredProc<> sp_get(m_ConnectionDest, L"usp_TradeSeq_Get"); sp_get << (int)lMaxSeqNum; sp_get << (int)lMaxSeqNum; sp_get << CDBNull(); sp_get << (unsigned char)1; rs.Open (sp_get); if(rs.IsEOF()) { CTracer::Trace(CTracer::enMtError, _T("Failed to retrieve trade from database - trade with ExecID '%d' does not exist."), Trade.nTradeID); dwRes = ERROR_NO_DATA_DETECTED; } else if (GetMode() == MODE_INTRADAY) { HRESULT hRes; if(FAILED(hRes = FillTradeUpdate(rs, Trade))) { CTracer::Trace(CTracer::enMtError, _T("Failed to fill TradeUpdate message.")); dwRes = ERROR_INVALID_PARAMETER; } else if(hRes == S_FALSE) { CTracer::Trace(CTracer::enMtError, _T("Failed to retrieve trade from database - trade with the same ExecID '%d' does not exist."), Trade.nTradeID); dwRes = ERROR_NO_DATA_DETECTED; } Publish(Trade); if (::WaitForSingleObject(GetStopEventHandle(), CSettings::m_nPublishDelayTime) == WAIT_OBJECT_0) { return _ERROR_NEED_TO_STOP; } } break; } default: dwRes = ERROR_INVALID_PARAMETER; break; } bOk = true; } catch(_com_error& e) { _bstr_t bsError = "Failed to store trade in database : " + m_ConnectionDest.GetErrorMessage(); CTracer::Trace(CTracer::enMtError, bsError); pair<TDBFailsStore::iterator, bool> pairResult = m_DBFails.insert(Trade.nTradeID); if (--dwTries) { Reconnect(); } else { CTracer::Trace(CTracer::enMtError, _T("CRITICAL ERROR : FAILED TO STORE TRADE IN DATABASE.")); if(false)//Uncomment this Oleg StoreInFile(Trade) != 0 { CTracer::Trace(CTracer::enMtError, _T("CRITICAL ERROR : FAILED TO STORE TRADE IN FILE.")); CTracer::Trace(CTracer::enMtError, _T("MANUAL INTERVENTION IS REQUIRED. THE APPLICATION IS STOPPED.")); ExitProcess(-1); } else { BroadcastError(e.Error(), bsError); dwRes = ERROR_REMOTE_STORAGE_NOT_ACTIVE; bOk = true; } } } } while(!bOk); return dwRes; };