Refactor CacheDb. replace tuple by private class

This commit is contained in:
Фролов 2021-11-11 10:57:08 +05:00
parent e1ba4e1777
commit 1c91c31417
5 changed files with 39 additions and 33 deletions

View File

@ -1,6 +1,4 @@
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using System;
using System.Collections;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
@ -9,25 +7,18 @@ namespace AsbCloudInfrastructure.Services.Cache
public class CacheDb public class CacheDb
{ {
private readonly ConcurrentDictionary<string, (DateTime, IEnumerable)> cache = private readonly ConcurrentDictionary<string, CacheTableDataStore> cache =
new ConcurrentDictionary<string, (DateTime, IEnumerable)>(); new ConcurrentDictionary<string, CacheTableDataStore>();
private readonly TimeSpan obsolesenceTime = TimeSpan.FromMinutes(15);
public CacheTable<TEntity> GetCachedTable<TEntity>(DbContext context) public CacheTable<TEntity> GetCachedTable<TEntity>(DbContext context)
where TEntity : class where TEntity : class
{ {
var entityTypeName = typeof(TEntity).FullName; var nameOfTEntity = typeof(TEntity).FullName;
var cacheItem = cache.GetOrAdd(nameOfTEntity, (nameOfTEntity) => new CacheTableDataStore {
var cacheItem = cache.GetOrAdd(entityTypeName, (DateTime.Now, new List<TEntity>())); NameOfTEntity = nameOfTEntity,
Entities = new List<TEntity>(),
bool isCachedDataObsolete = DateTime.Now - cacheItem.Item1 > obsolesenceTime; });
var tableCache = new CacheTable<TEntity>(context, cacheItem); var tableCache = new CacheTable<TEntity>(context, cacheItem);
if (isCachedDataObsolete)
tableCache.Refresh(true);
return tableCache; return tableCache;
} }

View File

@ -14,21 +14,21 @@ namespace AsbCloudInfrastructure.Services.Cache
{ {
private const int semaphoreTimeout = 5_000; private const int semaphoreTimeout = 5_000;
private static readonly SemaphoreSlim semaphore = new(1); private static readonly SemaphoreSlim semaphore = new(1);
private static readonly TimeSpan minPeriodRefresh = TimeSpan.FromSeconds(5); private static readonly TimeSpan minPeriodRefresh = TimeSpan.FromSeconds(5);
private static readonly string nameOfTEntity = typeof(TEntity).Name; private static readonly string nameOfTEntity = typeof(TEntity).Name;
private readonly DbContext context; private readonly CacheTableDataStore data;
private (DateTime refreshDate, IEnumerable entities) data;
private readonly List<TEntity> cached; private readonly List<TEntity> cached;
private readonly DbContext context;
private readonly DbSet<TEntity> dbSet; private readonly DbSet<TEntity> dbSet;
internal CacheTable(DbContext context, (DateTime refreshDate, IEnumerable entities) data) internal CacheTable(DbContext context, CacheTableDataStore data)
{ {
this.context = context; this.context = context;
this.data = data; this.data = data;
dbSet = context.Set<TEntity>(); dbSet = context.Set<TEntity>();
cached = (List<TEntity>)data.entities; cached = (List<TEntity>)data.Entities;
if (cached.Count == 0) if ((cached.Count == 0)||data.IsObsolete)
Refresh(false); Refresh(false);
} }
@ -52,7 +52,7 @@ namespace AsbCloudInfrastructure.Services.Cache
} }
catch (Exception ex) catch (Exception ex)
{ {
Trace.WriteLine($"{DateTime.Now:yyyy.MM.dd HH:mm:ss:fff} error in CacheTable<{typeof(TEntity).Name}>.Sync()"); Trace.WriteLine($"{DateTime.Now:yyyy.MM.dd HH:mm:ss:fff} error in CacheTable<{nameOfTEntity}>.Sync()");
Trace.WriteLine(ex.Message); Trace.WriteLine(ex.Message);
Trace.WriteLine(ex.StackTrace); Trace.WriteLine(ex.StackTrace);
} }
@ -81,7 +81,7 @@ namespace AsbCloudInfrastructure.Services.Cache
} }
catch (Exception ex) catch (Exception ex)
{ {
Trace.WriteLine($"{DateTime.Now:yyyy.MM.dd HH:mm:ss:fff} error in CacheTable<{typeof(TEntity).Name}>.SyncAsync()"); Trace.WriteLine($"{DateTime.Now:yyyy.MM.dd HH:mm:ss:fff} error in CacheTable<{nameOfTEntity}>.SyncAsync()");
Trace.WriteLine(ex.Message); Trace.WriteLine(ex.Message);
Trace.WriteLine(ex.StackTrace); Trace.WriteLine(ex.StackTrace);
} }
@ -94,26 +94,26 @@ namespace AsbCloudInfrastructure.Services.Cache
private void InternalRefresh(bool force) private void InternalRefresh(bool force)
{ {
if (force || data.refreshDate + minPeriodRefresh > DateTime.Now) if (force || data.LastResreshDate + minPeriodRefresh < DateTime.Now)
{ {
cached.Clear(); cached.Clear();
var entities = dbSet.AsNoTracking().ToList(); var entities = dbSet.AsNoTracking().ToList();
Trace.WriteLine($"CacheTable<{nameOfTEntity}> refresh"); Trace.WriteLine($"CacheTable<{nameOfTEntity}> refresh");
cached.AddRange(entities); cached.AddRange(entities);
data.refreshDate = DateTime.Now; data.LastResreshDate = DateTime.Now;
} }
} }
private async Task InternalRefreshAsync(bool force, CancellationToken token = default) private async Task InternalRefreshAsync(bool force, CancellationToken token = default)
{ {
if (force || data.refreshDate + minPeriodRefresh > DateTime.Now) if (force || data.LastResreshDate + minPeriodRefresh < DateTime.Now)
{ {
cached.Clear(); cached.Clear();
var entities = await context.Set<TEntity>().AsNoTracking() var entities = await context.Set<TEntity>().AsNoTracking()
.ToListAsync(token).ConfigureAwait(false); .ToListAsync(token).ConfigureAwait(false);
Trace.WriteLine($"CacheTable<{nameOfTEntity}> refreshAsync"); Trace.WriteLine($"CacheTable<{nameOfTEntity}> refreshAsync");
cached.AddRange(entities); cached.AddRange(entities);
data.refreshDate = DateTime.Now; data.LastResreshDate = DateTime.Now;
} }
} }

View File

@ -0,0 +1,15 @@
using System;
using System.Collections;
namespace AsbCloudInfrastructure.Services.Cache
{
class CacheTableDataStore
{
public string NameOfTEntity { get; set; }
public DateTime LastResreshDate { get; set; }
public IEnumerable Entities { get; set; }
public TimeSpan ObsolesenceTime { get; set; } = TimeSpan.FromMinutes(15);
public bool IsObsolete => (DateTime.Now - LastResreshDate > ObsolesenceTime);
}
}

View File

@ -143,7 +143,7 @@ namespace AsbCloudInfrastructure.Services
var telemetriesSrcIdsSql = $"({string.Join(',', telemetriesSrcIds)})"; var telemetriesSrcIdsSql = $"({string.Join(',', telemetriesSrcIds)})";
var telemetryInfoAndUid = telemetriesGrade var (RemoteUid, Info) = telemetriesGrade
.Where(t => t.Info != null) .Where(t => t.Info != null)
.OrderByDescending(t => t.Id) .OrderByDescending(t => t.Id)
.Select(t => (t.RemoteUid, t.Info)) .Select(t => (t.RemoteUid, t.Info))
@ -164,8 +164,8 @@ namespace AsbCloudInfrastructure.Services
try try
{ {
var telemetryDst = db.Telemetries.FirstOrDefault(t => t.Id == telemetryDestId); var telemetryDst = db.Telemetries.FirstOrDefault(t => t.Id == telemetryDestId);
telemetryDst.RemoteUid = telemetryInfoAndUid.RemoteUid; telemetryDst.RemoteUid = RemoteUid;
telemetryDst.Info = telemetryInfoAndUid.Info; telemetryDst.Info = Info;
if (wellId != default) if (wellId != default)
{ {

View File

@ -101,7 +101,7 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
{ {
Id = well.Id, Id = well.Id,
Caption = well.Caption, Caption = well.Caption,
WellType = wellType.Caption, WellType = wellType?.Caption ?? "",
IdState = well.IdState, IdState = well.IdState,
State = wellService.GetStateText(well.IdState), State = wellService.GetStateText(well.IdState),
LastTelemetryDate = wellService.GetLastTelemetryDate(well.Id), LastTelemetryDate = wellService.GetLastTelemetryDate(well.Id),
@ -384,7 +384,7 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
return tvd; return tvd;
} }
private List<Tuple<WellOperation, WellOperation>> MergeArraysBySections( private static List<Tuple<WellOperation, WellOperation>> MergeArraysBySections(
IEnumerable<int> sectionsIds, IEnumerable<int> sectionsIds,
IOrderedEnumerable<WellOperation> wellOperationsPlan, IOrderedEnumerable<WellOperation> wellOperationsPlan,
IOrderedEnumerable<WellOperation> wellOperationsFact) IOrderedEnumerable<WellOperation> wellOperationsFact)