} // ProcessRequest() // // // ************************************************* // **** Process Query() **** // ************************************************* private void ProcessQuery(EventArgs eventArgs) { Type type = eventArgs.GetType(); if (type == typeof(DB.Queries.ExchangeInfoQuery)) { m_ExchInfo = (DB.Queries.ExchangeInfoQuery)eventArgs; // Just store this info for later. } else if (type == typeof(DB.Queries.ProductInfoQuery)) { m_ProductInfo = (DB.Queries.ProductInfoQuery)eventArgs; // just store this info for later. } else if (type == typeof(DB.Queries.InstrumentInfoQuery)) { // Extract instr details from this result. DB.Queries.InstrumentInfoQuery query = (DB.Queries.InstrumentInfoQuery)eventArgs; if (query.Status == DB.Queries.QueryStatus.Failed) { Log.NewEntry(LogLevel.Warning, "ProcessQuery: Failed to find instrument {0} in database.", query.InstrumentName); } else if (query.Results == null || query.Results.Count == 0) { Log.NewEntry(LogLevel.Warning, "ProcessQuery: Failed to create details for {0} from database.", query.InstrumentName); } else { // Extract details from the query results DB.Queries.InstrumentInfoItem item = query.Results[0]; // I ask for instruments one at a time. InstrumentDetails details; if (item.TryGetInstrumentDetails(query.InstrumentName, out details)) { if (TryAddInstrumentDetails(query.InstrumentName, details)) { Log.NewEntry(LogLevel.Minor, "ProcessQuery: Added instr details for {0}.", query.InstrumentName); List <InstrumentName> instrNamesFound = new List <InstrumentName>(); instrNamesFound.Add(query.InstrumentName); base.OnInstrumentFound(instrNamesFound); m_IsResubmitPendingRequests = true; } else { Log.NewEntry(LogLevel.Warning, "ProcessQuery: Failed to add instr details for {0}.", query.InstrumentName); } } else { Log.NewEntry(LogLevel.Warning, "ProcessQuery: Failed to create instr details for {0}.", query.InstrumentName); } } // Mark this query as completed. if (m_PendingInstrumentQueries.Contains(query.InstrumentName)) { m_PendingInstrumentQueries.Remove(query.InstrumentName); // remove the query, it's finished. } } else if (type == typeof(DB.Queries.MarketDataQuery)) { DB.Queries.MarketDataQuery query = (DB.Queries.MarketDataQuery)eventArgs; int id; if (m_PendingMarketDataQueries.Contains(query)) { m_PendingMarketDataQueries.Remove(query); if (query.Status == DB.Queries.QueryStatus.Failed) { Log.NewEntry(LogLevel.Warning, "ProcessQuery: Failed to find instrument {0} in database.", query.InstrumentName); } else if (TryLookupInstrumentID(query.InstrumentName, out id)) { // Books for this instrument already exist. // In future, this occurs when we ask for mode data for pre-existing instrument. Log.NewEntry(LogLevel.Warning, "ProcessQuery: Query {1} for existing market {0}.", query.InstrumentName, query.QueryID); } else { // No book yet exists for this instrument. if (TryCreateNewBook(query.InstrumentName)) { // New book created. Log.NewEntry(LogLevel.Major, "ProcessQuery: Created book for instrument {0}.", query.InstrumentName); if (TryLookupInstrumentID(query.InstrumentName, out id)) { if (query.Result == null || query.Result.Count < 10) { Log.NewEntry(LogLevel.Warning, "ProcessQuery: Have no market data for instrument {0}.", query.InstrumentName); } // Create the MarketDataItem holder m_MarketItems.Add(id, new List <DB.Queries.MarketDataItem>(query.Result)); m_MarketItemPtrs.Add(id, 0); // set starting position to zero. // If this is first instrument data call back, initial the sim variables. if (!m_IsSimInitialized && m_MarketItems[id].Count > 0) { m_UtcNow = m_MarketItems[id][0].UnixTime; DateTime dt = this.LocalTime; // test m_IsSimInitialized = true; } } // Fire book created event. List <InstrumentName> booksCreated = new List <InstrumentName>(); booksCreated.Add(query.InstrumentName); OnMarketBookCreated(booksCreated); } else { Log.NewEntry(LogLevel.Major, "ProcessQuery: Failed to create new book for {0}.", query.InstrumentName); } } } } // // Test for readiness // if (m_IsDatabaseInitialized == false && m_ExchInfo != null && m_ProductInfo != null) { m_IsDatabaseInitialized = true; Log.NewEntry(LogLevel.Minor, "ProcessQuery: Loading database tables complete. Submitting {0} pending requests.", m_PendingRequests.Count); while (m_PendingRequests.Count > 0) { RequestEventArg <RequestCode> request = m_PendingRequests[0]; m_PendingRequests.RemoveAt(0); this.HubEventEnqueue(request); } } }// ProcessQuery
} // HubEventHandler() // // // // ************************************************* // **** Process Request() **** // ************************************************* private void ProcessRequest(RequestEventArg <RequestCode> eventArgs) { switch (eventArgs.RequestType) { case RequestCode.RequestServers: // This is trigger automatically at Start() request. // Here, we make all the conenctions necessary for collecting market data, info, etc. // Connect to the desired database. if (m_DatabaseReader == null) { // Search for database service. IService iService = null; if (AppServices.GetInstance().TryGetService("DatabaseReaderWriter", out iService)) { // Found database writer already in services. m_DatabaseReader = (DB.DatabaseReaderWriter)iService; m_DatabaseReader.QueryResponse += new EventHandler(this.HubEventEnqueue); } else { // Create db our own writer. m_DBInfo = DB.DatabaseInfo.Create(m_DBLocation); AppServices.GetInstance().TryAddService(m_DBInfo); m_DatabaseReader = new DB.DatabaseReaderWriter(m_DBInfo); m_DatabaseReader.QueryResponse += new EventHandler(this.HubEventEnqueue); m_DatabaseReader.Start(); } // Request info about exchanges and all products. DB.Queries.QueryBase query = new DB.Queries.ExchangeInfoQuery(); m_DatabaseReader.SubmitAsync(query); query = new DB.Queries.ProductInfoQuery(); m_DatabaseReader.SubmitAsync(query); } else { Log.NewEntry(LogLevel.Major, "ProcessRequest: Ignoring additional call to RequestServers."); } break; case RequestCode.RequestProducts: if (!m_IsDatabaseInitialized) { m_PendingRequests.Add(eventArgs); } else { } break; case RequestCode.RequestInstruments: if (!m_IsDatabaseInitialized) { m_PendingRequests.Add(eventArgs); } else { foreach (object o in eventArgs.Data) { // Validate this instrument request if (!(o is InstrumentName)) { continue; } InstrumentName instrName = (InstrumentName)o; InstrumentDetails instrDetails; if (!TryGetInstrumentDetails(instrName, out instrDetails) && m_PendingInstrumentQueries.Contains(instrName) != true) { // Details not exist yet and we have not requested them yet. Request them. Log.NewEntry(LogLevel.Minor, "ProcessRequest: Requesting instr details for {0}.", instrName); m_PendingInstrumentQueries.Add(instrName); // add to pending list (so we can't spam db). DB.Queries.InstrumentInfoQuery query = new DB.Queries.InstrumentInfoQuery(); query.InstrumentName = instrName; m_DatabaseReader.SubmitAsync(query); } } //next data object o } break; case RequestCode.RequestInstrumentPriceSubscription: if (!m_IsDatabaseInitialized) { m_PendingRequests.Add(eventArgs); } else { foreach (object o in eventArgs.Data) { // Validate this instrument request if (!(o is InstrumentName)) { continue; } InstrumentName instrName = (InstrumentName)o; int instrId = 0; InstrumentDetails instrDetails; if (TryLookupInstrumentID(instrName, out instrId) && instrId > -1) { continue; // instrument already has a book id! } // Get the isntrument details first, and make sure details exist. if (!TryGetInstrumentDetails(instrName, out instrDetails)) { // Details not exist yet. Request them. Log.NewEntry(LogLevel.Minor, "ProcessRequest: Need instr details for {0}. Delaying mkt subscription.", instrName); m_PendingRequests.Add(eventArgs); // push onto pending list for later resubmission. base.RequestInstruments(instrName); } else { // Make sure we have not already requested this data. bool isRequestAlreadyPending = false; foreach (DB.Queries.MarketDataQuery query in m_PendingMarketDataQueries) { if (query.InstrumentName == instrName) { isRequestAlreadyPending = true; break; } } if (isRequestAlreadyPending) { Log.NewEntry(LogLevel.Major, "ProcessRequest: Market data for {0} pending. Ignore", instrName); } else { // This request is NOT already pending, so request data now. DB.Queries.MarketDataQuery query = new DB.Queries.MarketDataQuery(); query.InstrumentName = instrName; query.StartDate = m_MktDataStartDateTime.ToUniversalTime(); // Query times in UTC. query.EndDate = query.StartDate.AddHours(m_MktDataBlockSize); m_PendingMarketDataQueries.Add(query); // add to pending list (so we can't spam db). Log.NewEntry(LogLevel.Major, "ProcessRequest: Requesting mkt data for {0} from {1} ({2} hours).", instrName, query.StartDate.ToString("MMM-dd-yyyy HH:mm:ss"), m_MktDataBlockSize); m_DatabaseReader.SubmitAsync(query); } } } } break; case RequestCode.RequestShutdown: if (m_DatabaseReader != null) { m_DatabaseReader.RequestStop(); m_DatabaseReader = null; } base.Stop(); break; default: Log.NewEntry(LogLevel.Major, "ProcessRequest: Unknown request."); break; } //switch on request type. } // ProcessRequest()