using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Tiku.Application.Security; using Tiku.Application.Tenancy; namespace Tiku.Infrastructure.Security; internal sealed class TenantFeatureCacheInvalidator( IMemoryCache memoryCache, IServiceProvider serviceProvider, ITenantRuntimeCacheInvalidator runtimeCacheInvalidator, ILogger logger) : ITenantFeatureCacheInvalidator { public async Task InvalidateAsync(Guid tenantId, CancellationToken cancellationToken = default) { RemoveMemory(tenantId); await runtimeCacheInvalidator.InvalidateAsync(tenantId, cancellationToken); var distributedCache = serviceProvider.GetService(); if (distributedCache is not null) { try { await Task.WhenAll( distributedCache.RemoveAsync(TenantFeatureSnapshotProvider.CacheKey(tenantId, FeatureAccessOperation.Read), cancellationToken), distributedCache.RemoveAsync(TenantFeatureSnapshotProvider.CacheKey(tenantId, FeatureAccessOperation.Write), cancellationToken)); } catch (Exception exception) when (exception is not OperationCanceledException) { logger.LogWarning(exception, "Tenant feature distributed cache invalidation failed for tenant {TenantId}.", tenantId); } } } private void RemoveMemory(Guid tenantId) { memoryCache.Remove(TenantFeatureSnapshotProvider.CacheKey(tenantId, FeatureAccessOperation.Read)); memoryCache.Remove(TenantFeatureSnapshotProvider.CacheKey(tenantId, FeatureAccessOperation.Write)); } }