Changed CacheTable internal List to ConcurrentBag

This commit is contained in:
KharchenkoVV 2021-09-29 10:26:25 +05:00
parent ff1a75858b
commit 6a4b426aa2
3 changed files with 68 additions and 70 deletions

View File

@ -17,7 +17,10 @@ namespace AsbCloudDevOperations
{ {
var host = "http://localhost:5000"; var host = "http://localhost:5000";
var json = JsonSerializer.Serialize(new List<TelemetryDataSaubDto>()); var json = JsonSerializer.Serialize(new List<TelemetryDataSaubDto>()
{
new TelemetryDataSaubDto()
});
var stringContent = new StringContent(json, Encoding.UTF8, "application/json"); var stringContent = new StringContent(json, Encoding.UTF8, "application/json");

View File

@ -8,7 +8,9 @@ namespace AsbCloudInfrastructure.Services.Cache
public class CacheDb public class CacheDb
{ {
private readonly ConcurrentDictionary<string, (DateTime, IEnumerable<object>)> cache = new ConcurrentDictionary<string, (DateTime, IEnumerable<object>)>(); private readonly ConcurrentDictionary<string, (DateTime, object)> cache =
new ConcurrentDictionary<string, (DateTime, object)>();
private readonly TimeSpan obsolesenceTime = TimeSpan.FromMinutes(15); private readonly TimeSpan obsolesenceTime = TimeSpan.FromMinutes(15);
public CacheTable<TEntity> GetCachedTable<TEntity>(DbContext context) public CacheTable<TEntity> GetCachedTable<TEntity>(DbContext context)
@ -17,7 +19,7 @@ namespace AsbCloudInfrastructure.Services.Cache
var entityTypeName = typeof(TEntity).FullName; var entityTypeName = typeof(TEntity).FullName;
if (!cache.ContainsKey(entityTypeName)) if (!cache.ContainsKey(entityTypeName))
cache[entityTypeName] = (DateTime.Now, new List<TEntity>(8)); cache[entityTypeName] = (DateTime.Now, new ConcurrentBag<TEntity>());
bool isCachedDataObsolete = DateTime.Now - cache[entityTypeName].Item1 > obsolesenceTime; bool isCachedDataObsolete = DateTime.Now - cache[entityTypeName].Item1 > obsolesenceTime;

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -11,15 +12,15 @@ namespace AsbCloudInfrastructure.Services.Cache
where TEntity : class where TEntity : class
{ {
private readonly DbContext context; private readonly DbContext context;
private (DateTime refreshDate, IEnumerable<object> entities) data; private (DateTime refreshDate, object entities) data;
private readonly List<TEntity> cached; private readonly ConcurrentBag<TEntity> cached;
private readonly DbSet<TEntity> dbSet; private readonly DbSet<TEntity> dbSet;
internal CacheTable(DbContext context, (DateTime refreshDate, IEnumerable<object> entities) data) internal CacheTable(DbContext context, (DateTime refreshDate, object entities) data)
{ {
this.context = context; this.context = context;
this.data = data; this.data = data;
this.cached = (List<TEntity>)data.entities; this.cached = (ConcurrentBag<TEntity>)data.entities;
dbSet = context.Set<TEntity>(); dbSet = context.Set<TEntity>();
} }
@ -27,41 +28,24 @@ namespace AsbCloudInfrastructure.Services.Cache
public int Refresh() public int Refresh()
{ {
if (cached.Any()) cached.Clear();
{
try
{
cached.Clear();
}
catch
{
// ignore
// TODO: figure out what the hell
}
}
var dbEntities = context.Set<TEntity>().AsNoTracking().ToList(); var dbEntities = context.Set<TEntity>().AsNoTracking().ToList();
cached.AddRange(dbEntities); foreach(var e in dbEntities)
cached.Add(e);
data.refreshDate = DateTime.Now; data.refreshDate = DateTime.Now;
return cached.Count; return cached.Count;
} }
public async Task<int> RefreshAsync(CancellationToken token = default) public async Task<int> RefreshAsync(CancellationToken token = default)
{ {
if (cached.Any()) cached.Clear();
{
try var dbEntities = await context.Set<TEntity>().AsNoTracking()
{ .ToListAsync(token).ConfigureAwait(false);
cached.Clear();
} foreach (var e in dbEntities)
catch cached.Add(e);
{
// ignore
// TODO: figure out what the well
}
}
var dbEntities = await context.Set<TEntity>().AsNoTracking().ToListAsync(token).ConfigureAwait(false);
cached.AddRange(dbEntities);
data.refreshDate = DateTime.Now; data.refreshDate = DateTime.Now;
return cached.Count; return cached.Count;
} }
@ -202,33 +186,40 @@ namespace AsbCloudInfrastructure.Services.Cache
return result; return result;
} }
public IEnumerable<TEntity> Mutate(Func<TEntity, bool> predicate, Action<TEntity> mutation) //public IEnumerable<TEntity> Mutate(Func<TEntity, bool> predicate,
{ // Action<TEntity> mutation)
var dbEntities = dbSet.Where(predicate); //{
if (dbEntities.Any()) // var dbEntities = dbSet.Where(predicate);
{ // if (dbEntities.Any())
foreach (var dbEntity in dbEntities) // {
mutation(dbEntity); // foreach (var dbEntity in dbEntities)
context.SaveChanges(); // mutation(dbEntity);
} // context.SaveChanges();
cached.RemoveAll(e => predicate(e)); // }
cached.AddRange(dbEntities); // var matchedByPredicate = cached.Select(el => predicate(el));
return dbEntities; // foreach (var item in matchedByPredicate)
} // cached.TryTake(out var t);
// cached = cached.RemoveAll(e => predicate(e));
// foreach (var e in dbEntities)
// cached.Add(e);
// return dbEntities;
//}
public async Task<IEnumerable<TEntity>> MutateAsync(Func<TEntity, bool> predicate, Action<TEntity> mutation, CancellationToken token = default) //public async Task<IEnumerable<TEntity>> MutateAsync(Func<TEntity,
{ // bool> predicate, Action<TEntity> mutation, CancellationToken token = default)
var dbEntities = dbSet.Where(predicate); //{
if (dbEntities.Any()) // var dbEntities = dbSet.Where(predicate);
{ // if (dbEntities.Any())
foreach (var dbEntity in dbEntities) // {
mutation(dbEntity); // foreach (var dbEntity in dbEntities)
await context.SaveChangesAsync(token).ConfigureAwait(false); // mutation(dbEntity);
} // await context.SaveChangesAsync(token).ConfigureAwait(false);
cached.RemoveAll(e => predicate(e)); // }
cached.AddRange(dbEntities); // cached.RemoveAll(e => predicate(e));
return dbEntities; // foreach (var e in dbEntities)
} // cached.Add(e);
// return dbEntities;
//}
public TEntity Upsert(TEntity entity) public TEntity Upsert(TEntity entity)
{ {
@ -286,34 +277,34 @@ namespace AsbCloudInfrastructure.Services.Cache
public void Remove(Func<TEntity, bool> predicate) public void Remove(Func<TEntity, bool> predicate)
{ {
cached.RemoveAll(e => predicate(e));
dbSet.RemoveRange(dbSet.Where(predicate)); dbSet.RemoveRange(dbSet.Where(predicate));
context.SaveChanges(); context.SaveChanges();
Refresh();
return; return;
} }
public async Task RemoveAsync(Func<TEntity, bool> predicate, CancellationToken token = default) public async Task RemoveAsync(Func<TEntity, bool> predicate, CancellationToken token = default)
{ {
cached.RemoveAll(e => predicate(e));
dbSet.RemoveRange(dbSet.Where(predicate)); dbSet.RemoveRange(dbSet.Where(predicate));
await context.SaveChangesAsync(token).ConfigureAwait(false); await context.SaveChangesAsync(token).ConfigureAwait(false);
await RefreshAsync(token).ConfigureAwait(false);
return; return;
} }
public TEntity Insert(TEntity entity) public TEntity Insert(TEntity entity)
{ {
var dbEntity = dbSet.Add(entity).Entity; var entry = dbSet.Add(entity);
context.SaveChanges(); context.SaveChanges();
cached.Add(dbEntity); cached.Add(entry.Entity);
return dbEntity; return entry.Entity;
} }
public async Task<TEntity> InsertAsync(TEntity entity, CancellationToken token = default) public async Task<TEntity> InsertAsync(TEntity entity, CancellationToken token = default)
{ {
var dbEntity = dbSet.Add(entity).Entity; var entry = dbSet.Add(entity);
await context.SaveChangesAsync(token).ConfigureAwait(false); await context.SaveChangesAsync(token).ConfigureAwait(false);
cached.Add(dbEntity); cached.Add(entry.Entity);
return dbEntity; return entry.Entity;
} }
public IEnumerable<TEntity> Insert(IEnumerable<TEntity> newEntities) public IEnumerable<TEntity> Insert(IEnumerable<TEntity> newEntities)
@ -322,7 +313,8 @@ namespace AsbCloudInfrastructure.Services.Cache
foreach (var item in newEntities) foreach (var item in newEntities)
dbEntities.Add(dbSet.Add(item).Entity); dbEntities.Add(dbSet.Add(item).Entity);
context.SaveChanges(); context.SaveChanges();
cached.AddRange(dbEntities); foreach (var e in dbEntities)
cached.Add(e);
return dbEntities; return dbEntities;
} }
@ -332,7 +324,8 @@ namespace AsbCloudInfrastructure.Services.Cache
foreach (var item in newEntities) foreach (var item in newEntities)
dbEntities.Add(dbSet.Add(item).Entity); dbEntities.Add(dbSet.Add(item).Entity);
await context.SaveChangesAsync(token).ConfigureAwait(false); await context.SaveChangesAsync(token).ConfigureAwait(false);
cached.AddRange(dbEntities); foreach (var e in dbEntities)
cached.Add(e);
return dbEntities; return dbEntities;
} }