private void ProcessSubscriptionRequest() { if (_subscriptionsPending) { return; } _lastSubscribeRequestUtcTime = DateTime.UtcNow; _subscriptionsPending = true; Task.Run(async() => { while (true) { DateTime requestTime; List <Symbol> symbolsToSubscribe; lock (_lockerSubscriptions) { requestTime = _lastSubscribeRequestUtcTime.Add(_subscribeDelay); // CoinAPI requires at least 5 seconds between hello messages if (_nextHelloMessageUtcTime != DateTime.MinValue && requestTime < _nextHelloMessageUtcTime) { requestTime = _nextHelloMessageUtcTime; } symbolsToSubscribe = _subscriptionManager.GetSubscribedSymbols().ToList(); } var timeToWait = requestTime - DateTime.UtcNow; int delayMilliseconds; if (timeToWait <= TimeSpan.Zero) { // minimum delay has passed since last subscribe request, send the Hello message SubscribeSymbols(symbolsToSubscribe); lock (_lockerSubscriptions) { _lastSubscribeRequestUtcTime = DateTime.UtcNow; if (_subscriptionManager.GetSubscribedSymbols().Count() == symbolsToSubscribe.Count) { // no more subscriptions pending, task finished _subscriptionsPending = false; break; } } delayMilliseconds = _subscribeDelay.Milliseconds; } else { delayMilliseconds = timeToWait.Milliseconds; } await Task.Delay(delayMilliseconds).ConfigureAwait(false); } }); }
/// <summary> /// Pumps a bunch of ticks into the queue /// </summary> private void PopulateQueue() { var symbols = _subscriptionManager.GetSubscribedSymbols(); foreach (var symbol in symbols) { var offsetProvider = GetTimeZoneOffsetProvider(symbol); var trades = SubscriptionManager.DefaultDataTypes()[symbol.SecurityType].Contains(TickType.Trade); var quotes = SubscriptionManager.DefaultDataTypes()[symbol.SecurityType].Contains(TickType.Quote); // emits 500k per second for (var i = 0; i < 500000; i++) { var now = TimeProvider.GetUtcNow(); if (trades) { _count++; _aggregator.Update(new Tick { Time = offsetProvider.ConvertFromUtc(now), Symbol = symbol, Value = 10 + (decimal)Math.Abs(Math.Sin(now.TimeOfDay.TotalMinutes)), TickType = TickType.Trade, Quantity = _random.Next(10, (int)_timer.Interval) }); } if (quotes) { _count++; var bid = 10 + (decimal)Math.Abs(Math.Sin(now.TimeOfDay.TotalMinutes)); var bidSize = _random.Next(10, (int)_timer.Interval); var askSize = _random.Next(10, (int)_timer.Interval); var time = offsetProvider.ConvertFromUtc(now); _aggregator.Update(new Tick(time, symbol, "", "", bid, bidSize, bid * 1.01m, askSize)); } } } }