< Summary

Information
Class: Services.CacheServices.Cache.EtProducerCache.EtProducerCache
Assembly: Services
File(s): /home/runner/work/Studio2Prod/Studio2Prod/AppRepository/CacheServices/Cache/EtProducerCache/EtProducerCache.cs
Line coverage
45%
Covered lines: 33
Uncovered lines: 39
Coverable lines: 72
Total lines: 140
Line coverage: 45.8%
Branch coverage
27%
Covered branches: 6
Total branches: 22
Branch coverage: 27.2%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
SetCache(...)100%11100%
GetCache(...)50%22100%
Get()83.33%6691.3%
Get()0%2040%
Update()100%210%
UpdateCacheIncrementally()0%4260%
RemoveProducerFromCache()0%620%
RemoveProducersFromCache()0%620%

File(s)

/home/runner/work/Studio2Prod/Studio2Prod/AppRepository/CacheServices/Cache/EtProducerCache/EtProducerCache.cs

#LineLine coverage
 1using Microsoft.EntityFrameworkCore;
 2using Microsoft.Extensions.Caching.Memory;
 3using Newtonsoft.Json;
 4using OzonDomains.Models;
 5using OzonRepositories.Context;
 6using Services.CacheServices;
 7
 8namespace Services.CacheServices.Cache.EtProducerCache
 9{
 10    public class EtProducerCache : IRedisAppCache<EtProducer>
 11    {
 12        private readonly IMemoryCache _memoryCache;
 13        private readonly JcEtalonContext _jcEtalonContext;
 14        private const string CacheKey = "EtProducers";
 15        private const int InitialLoadCount = 500;
 16        private const int IncrementCount = 100;
 117        private int _maxPage = 1;
 118        private int _maxItemsToLoad = InitialLoadCount;
 19
 120        public EtProducerCache(IMemoryCache memoryCache, JcEtalonContext jcEtalonContext)
 21        {
 122            _memoryCache = memoryCache;
 123            _jcEtalonContext = jcEtalonContext;
 124        }
 25
 26        private void SetCache(string key, object value, TimeSpan expiration)
 27        {
 128            var cacheEntryOptions = new MemoryCacheEntryOptions()
 129                .SetAbsoluteExpiration(expiration);
 130            _memoryCache.Set(key, value, cacheEntryOptions);
 131        }
 32
 33        private T? GetCache<T>(string key)
 34        {
 135            return _memoryCache.TryGetValue(key, out T? value) ? value : default;
 36        }
 37
 38        public async Task<List<EtProducer>> Get(int page)
 39        {
 140            var cachedEtProducers = GetCache<List<EtProducer>>(CacheKey);
 141            if (cachedEtProducers == null)
 42            {
 143                cachedEtProducers = (await _jcEtalonContext.EtProducers.OrderBy(e => e.Id).Take(InitialLoadCount).ToList
 144                    .ToList();
 145                _maxPage = 10;
 146                SetCache(CacheKey, cachedEtProducers, TimeSpan.FromMinutes(10));
 47            }
 48
 149            int requiredItemCount = page * IncrementCount;
 150            if (cachedEtProducers.Count < requiredItemCount)
 51            {
 152                int itemsToLoad = requiredItemCount - cachedEtProducers.Count;
 153                var additionalEtProducers = await _jcEtalonContext.EtProducers
 154                    .OrderBy(e => e.Id)
 155                    .Skip(cachedEtProducers.Count)
 156                    .Take(itemsToLoad)
 157                    .ToListAsync();
 58
 159                if (additionalEtProducers.Any())
 60                {
 061                    cachedEtProducers.AddRange(additionalEtProducers);
 062                    SetCache(CacheKey, cachedEtProducers, TimeSpan.FromMinutes(10));
 63                }
 64
 165                _maxPage = Math.Max(_maxPage, page);
 166                _maxItemsToLoad = itemsToLoad;
 67            }
 68
 169            return cachedEtProducers
 170                .Take(requiredItemCount)
 571                .OrderBy(e => e.Name)
 172                .ToList();
 173        }
 74
 75        public async Task<List<EtProducer>> Get()
 76        {
 077            var cachedEtProducers = GetCache<List<EtProducer>>(CacheKey);
 078            if (cachedEtProducers != null)
 079                return cachedEtProducers.OrderBy(e => e.Name).ToList();
 80
 081            await Update();
 082            cachedEtProducers = GetCache<List<EtProducer>>(CacheKey);
 83
 084            if (cachedEtProducers != null)
 085                return cachedEtProducers.OrderBy(e => e.Name).ToList();
 86
 087            throw new InvalidOperationException("Данные не найдены в кэше после обновления.");
 088        }
 89
 90        public async Task Update()
 91        {
 092            var producers = await _jcEtalonContext.EtProducers
 093                .OrderBy(e => e.Id)
 094                .Take(_maxItemsToLoad)
 095                .ToListAsync();
 096            SetCache(CacheKey, producers, TimeSpan.FromMinutes(10));
 097        }
 98
 99        public async Task UpdateCacheIncrementally(int producerId)
 100        {
 0101            var updatedProducer = await _jcEtalonContext.EtProducers
 0102                .FirstOrDefaultAsync(p => p.Id == producerId);
 0103            if (updatedProducer == null) return;
 104
 0105            var cachedEtProducers = GetCache<List<EtProducer>>(CacheKey) ?? new List<EtProducer>();
 0106            var existingProducerIndex = cachedEtProducers.FindIndex(p => p.Id == producerId);
 107
 0108            if (existingProducerIndex != -1)
 109            {
 0110                cachedEtProducers[existingProducerIndex] = updatedProducer;
 111            }
 112            else
 113            {
 0114                cachedEtProducers.Add(updatedProducer);
 115            }
 116
 0117            SetCache(CacheKey, cachedEtProducers, TimeSpan.FromMinutes(10));
 0118        }
 119
 120        public async Task RemoveProducerFromCache(int producerId)
 121        {
 0122            await Task.CompletedTask;
 0123            var cachedEtProducers = GetCache<List<EtProducer>>(CacheKey);
 0124            if (cachedEtProducers == null) return;
 125
 0126            cachedEtProducers.RemoveAll(p => p.Id == producerId);
 0127            SetCache(CacheKey, cachedEtProducers, TimeSpan.FromMinutes(10));
 0128        }
 129
 130        public async Task RemoveProducersFromCache(int[] producerIds)
 131        {
 0132            await Task.CompletedTask;
 0133            var cachedEtProducers = GetCache<List<EtProducer>>(CacheKey);
 0134            if (cachedEtProducers == null) return;
 135
 0136            cachedEtProducers.RemoveAll(p => producerIds.Contains(p.Id));
 0137            SetCache(CacheKey, cachedEtProducers, TimeSpan.FromMinutes(10));
 0138        }
 139    }
 140}