Пример #1
0
        private async Task TruncateCacheAsync()
        {
            // Shall not truncate cache while reloading data.
            if (_cacheInitalizationService.InitializationState != CacheInitializationState.Idle)
            {
                return;
            }

            SlotType activeSlot = await _redisCacheService.GetActiveSlotAsync(_marketType);

            var tasks = new List <Task>();

            foreach (var assetId in _historyRepository.GetStoredAssetPairs())
            {
                foreach (var priceType in Constants.StoredPriceTypes)
                {
                    foreach (var timeInterval in Constants.InitFromDbIntervals)
                    {
                        int candlesAmount = _amountOfCandlesToStore[timeInterval];

                        var intervals = _redisCacheService.GetRedisCacheIntervals(timeInterval);

                        foreach (var interval in intervals)
                        {
                            tasks.Add(_redisCacheService.TruncateCacheAsync(assetId, priceType, interval, GetIntervalCandlesAmount(candlesAmount, interval), activeSlot));
                        }
                    }
                }
            }

            await Task.WhenAll(tasks);
        }
Пример #2
0
        public async Task InitializeCacheAsync()
        {
            // Depending on cache invalidation period and on asset pairs amount, there may be a case when
            // the invalidation timer fires before the cache loading has stopped. This will be a signal
            // to skip timer-based invalidation.
            // Below we combine two approaches:
            // - we're exporting a fast signal for any timer-based routine that we have already been initializing the cache;
            // - and we additionally block all the cache-related operations for other parts of code.
            // The first is needed to avoid queueing of timer events. If we simply use blocks, we will finally face a problem
            // when cache initialization may become infinitly repeated. The second is important for avoidining a multi-threaded
            // write operations to the cache: if we've got a candle update set, we need to await for cache fill completion and
            // then proceed.
            lock (_initializationStateLocker)
            {
                if (InitializationState == CacheInitializationState.InProgress)
                {
                    return;
                }

                InitializationState = CacheInitializationState.InProgress;
            }

            await _cacheSem.WaitAsync();

            try
            {
                _log.Info(nameof(InitializeCacheAsync), "Caching candles history...");

                SlotType activeSlot = await _candlesCacheService.GetActiveSlotAsync(_marketType);

                //initialize cache to inactive slot
                SlotType initSlot = activeSlot == SlotType.Slot0
                    ? SlotType.Slot1
                    : SlotType.Slot0;

                var assetPairs = await _assetPairsManager.GetAllAsync();

                var now = _clock.UtcNow;

                foreach (var pairs in assetPairs.Where(a => _candlesHistoryRepository.CanStoreAssetPair(a.Id)).Batch(6))
                {
                    var tasks = pairs.Select(p => CacheAssetPairCandlesAsync(p, now, initSlot));
                    await Task.WhenAll(tasks);
                }

                await _candlesCacheService.InjectCacheValidityToken();                // Initial validation token set.

                await _candlesCacheService.SetActiveSlotAsync(_marketType, initSlot); //switch slots

                _log.Info(nameof(InitializeCacheAsync), "All candles history is cached");
            }
            finally
            {
                InitializationState = CacheInitializationState.Idle;
                _cacheSem.Release();
            }
        }
 public Task <SlotType> GetActiveSlotAsync()
 {
     return(_candlesCacheService.GetActiveSlotAsync());
 }