[WIP] Add debug output of entities

features/nuget_autobuild
Matija Koželj 2 years ago
parent 9381a4e4c6
commit 018a48dd65

@ -10,118 +10,120 @@ using System.Collections.Immutable;
namespace Connected.Entities.Caching; namespace Connected.Entities.Caching;
public abstract class EntityCacheClient<TEntity, TPrimaryKey> : StatefulCacheClient<TEntity, TPrimaryKey>, IEntityCacheClient<TEntity, TPrimaryKey> public abstract class EntityCacheClient<TEntity, TPrimaryKey> : StatefulCacheClient<TEntity, TPrimaryKey>, IEntityCacheClient<TEntity, TPrimaryKey>
where TEntity : class, IPrimaryKey<TPrimaryKey>, IEntity where TEntity : class, IPrimaryKey<TPrimaryKey>, IEntity
where TPrimaryKey : notnull where TPrimaryKey : notnull
{ {
protected EntityCacheClient(IEntityCacheContext context, string key) : base(context.Cache, key) protected EntityCacheClient(IEntityCacheContext context, string key) : base(context.Cache, key)
{ {
Context = context; Context = context;
} }
private IEntityCacheContext Context { get; } private IEntityCacheContext Context { get; }
protected override sealed async Task OnInitializing() protected override sealed async Task OnInitializing()
{ {
using var ctx = Context.ContextProvider.Create(); using var ctx = Context.ContextProvider.Create();
var transaction = ctx.GetService<ITransactionContext?>(); var transaction = ctx.GetService<ITransactionContext?>();
try try
{ {
if (await OnInitializing(ctx) is ImmutableList<TEntity> ds) if (await OnInitializing(ctx) is ImmutableList<TEntity> ds)
{ {
foreach (var r in ds) foreach (var r in ds)
Set(r.Id, r, TimeSpan.Zero); Set(r.Id, r, TimeSpan.Zero);
} }
if (transaction is not null) if (transaction is not null)
await transaction.Commit(); await transaction.Commit();
} }
catch catch
{ {
if (transaction is not null) if (transaction is not null)
await transaction.Rollback(); await transaction.Rollback();
throw; throw;
} }
} }
protected virtual async Task<ImmutableList<TEntity>?> OnInitializing(IContext context) protected virtual async Task<ImmutableList<TEntity>?> OnInitializing(IContext context)
{ {
if (context.GetService<IStorageProvider>() is not IStorageProvider db) if (context.GetService<IStorageProvider>() is not IStorageProvider db)
return default; return default;
return await (from dc in db.Open<TEntity>() return await (from dc in db.Open<TEntity>()
select dc).AsEntities(); select dc).AsEntities();
} }
protected override async Task OnInvalidate(TPrimaryKey id) protected override async Task OnInvalidate(TPrimaryKey id)
{ {
using var ctx = Context.ContextProvider.Create(); using var ctx = Context.ContextProvider.Create();
var transaction = ctx.GetService<ITransactionContext>(); var transaction = ctx.GetService<ITransactionContext>();
try try
{ {
if (OnInvalidating(ctx, id) is TEntity entity && entity is IPrimaryKey<TPrimaryKey> pk) if (OnInvalidating(ctx, id) is TEntity entity && entity is IPrimaryKey<TPrimaryKey> pk)
Set(pk.Id, entity, TimeSpan.Zero); Set(pk.Id, entity, TimeSpan.Zero);
if (transaction is not null) if (transaction is not null)
await transaction.Commit(); await transaction.Commit();
} }
catch catch
{ {
if (transaction is not null) if (transaction is not null)
await transaction.Rollback(); await transaction.Rollback();
throw; throw;
} }
} }
protected virtual async Task<TEntity?> OnInvalidating(IContext context, TPrimaryKey id) protected virtual async Task<TEntity?> OnInvalidating(IContext context, TPrimaryKey id)
{ {
if (context.GetService<IStorageProvider>() is not IStorageProvider provider) if (context.GetService<IStorageProvider>() is not IStorageProvider provider)
return default; return default;
return await (from dc in provider.Open<TEntity>() var entities = provider.Open<TEntity>().AsEntities();
where TypeComparer.Compare(dc.Id, id)
select dc).AsEntity(); return await (from dc in provider.Open<TEntity>()
} where TypeComparer.Compare(dc.Id, id)
select dc).AsEntity();
async Task IEntityCacheClient<TEntity, TPrimaryKey>.Refresh(TPrimaryKey id) }
{
await Refresh(id); async Task IEntityCacheClient<TEntity, TPrimaryKey>.Refresh(TPrimaryKey id)
} {
await Refresh(id);
async Task IEntityCacheClient<TEntity, TPrimaryKey>.Remove(TPrimaryKey id) }
{
await Remove(id); async Task IEntityCacheClient<TEntity, TPrimaryKey>.Remove(TPrimaryKey id)
} {
await Remove(id);
protected override void Set(TPrimaryKey id, TEntity instance) }
{
Set(id, instance, TimeSpan.Zero); protected override void Set(TPrimaryKey id, TEntity instance)
} {
Set(id, instance, TimeSpan.Zero);
protected override void Set(TPrimaryKey id, TEntity instance, TimeSpan duration) }
{
if (instance is IConcurrentEntity<TPrimaryKey> concurrent) protected override void Set(TPrimaryKey id, TEntity instance, TimeSpan duration)
{ {
if (Get(id) is TEntity existing && existing is IConcurrentEntity<TPrimaryKey> existingConcurrent) if (instance is IConcurrentEntity<TPrimaryKey> concurrent)
{ {
lock (existingConcurrent) if (Get(id) is TEntity existing && existing is IConcurrentEntity<TPrimaryKey> existingConcurrent)
{ {
if (existingConcurrent.Sync != concurrent.Sync) lock (existingConcurrent)
throw new InvalidOperationException(SR.ErrConcurrent); {
if (existingConcurrent.Sync != concurrent.Sync)
concurrent.GetType().GetProperty(nameof(IConcurrentEntity<TPrimaryKey>.Sync))?.SetValue(concurrent, concurrent.Sync + 1); throw new InvalidOperationException(SR.ErrConcurrent);
Set(id, instance, duration); concurrent.GetType().GetProperty(nameof(IConcurrentEntity<TPrimaryKey>.Sync))?.SetValue(concurrent, concurrent.Sync + 1);
return; Set(id, instance, duration);
}
} return;
} }
}
base.Set(id, instance, duration); }
}
base.Set(id, instance, duration);
}
} }

Loading…
Cancel
Save