[WIP] Add debug output of entities
This commit is contained in:
		
							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();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async Task IEntityCacheClient<TEntity, TPrimaryKey>.Refresh(TPrimaryKey id)
 | 
							return await (from dc in provider.Open<TEntity>()
 | 
				
			||||||
    {
 | 
											  where TypeComparer.Compare(dc.Id, id)
 | 
				
			||||||
        await Refresh(id);
 | 
											  select dc).AsEntity();
 | 
				
			||||||
    }
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async Task IEntityCacheClient<TEntity, TPrimaryKey>.Remove(TPrimaryKey id)
 | 
						async Task IEntityCacheClient<TEntity, TPrimaryKey>.Refresh(TPrimaryKey id)
 | 
				
			||||||
    {
 | 
						{
 | 
				
			||||||
        await Remove(id);
 | 
							await Refresh(id);
 | 
				
			||||||
    }
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected override void Set(TPrimaryKey id, TEntity instance)
 | 
						async Task IEntityCacheClient<TEntity, TPrimaryKey>.Remove(TPrimaryKey id)
 | 
				
			||||||
    {
 | 
						{
 | 
				
			||||||
        Set(id, instance, TimeSpan.Zero);
 | 
							await Remove(id);
 | 
				
			||||||
    }
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected override void Set(TPrimaryKey id, TEntity instance, TimeSpan duration)
 | 
						protected override void Set(TPrimaryKey id, TEntity instance)
 | 
				
			||||||
    {
 | 
						{
 | 
				
			||||||
        if (instance is IConcurrentEntity<TPrimaryKey> concurrent)
 | 
							Set(id, instance, TimeSpan.Zero);
 | 
				
			||||||
        {
 | 
						}
 | 
				
			||||||
            if (Get(id) is TEntity existing && existing is IConcurrentEntity<TPrimaryKey> existingConcurrent)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                lock (existingConcurrent)
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    if (existingConcurrent.Sync != concurrent.Sync)
 | 
					 | 
				
			||||||
                        throw new InvalidOperationException(SR.ErrConcurrent);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    concurrent.GetType().GetProperty(nameof(IConcurrentEntity<TPrimaryKey>.Sync))?.SetValue(concurrent, concurrent.Sync + 1);
 | 
						protected override void Set(TPrimaryKey id, TEntity instance, TimeSpan duration)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (instance is IConcurrentEntity<TPrimaryKey> concurrent)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								if (Get(id) is TEntity existing && existing is IConcurrentEntity<TPrimaryKey> existingConcurrent)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									lock (existingConcurrent)
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										if (existingConcurrent.Sync != concurrent.Sync)
 | 
				
			||||||
 | 
											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);
 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        base.Set(id, instance, duration);
 | 
										return;
 | 
				
			||||||
    }
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							base.Set(id, instance, duration);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user