diff --git a/framework/src/Volo.Abp.Caching/Volo/Abp/Caching/CacheOptions.cs b/framework/src/Volo.Abp.Caching/Volo/Abp/Caching/CacheOptions.cs index ac8af06165..70f13c6b18 100644 --- a/framework/src/Volo.Abp.Caching/Volo/Abp/Caching/CacheOptions.cs +++ b/framework/src/Volo.Abp.Caching/Volo/Abp/Caching/CacheOptions.cs @@ -1,7 +1,6 @@ using Microsoft.Extensions.Caching.Distributed; using System; using System.Collections.Generic; -using System.Text; namespace Volo.Abp.Caching { diff --git a/framework/src/Volo.Abp.Caching/Volo/Abp/Caching/DistributedCache.cs b/framework/src/Volo.Abp.Caching/Volo/Abp/Caching/DistributedCache.cs index 9a8aa3e443..ebe2bf0de3 100644 --- a/framework/src/Volo.Abp.Caching/Volo/Abp/Caching/DistributedCache.cs +++ b/framework/src/Volo.Abp.Caching/Volo/Abp/Caching/DistributedCache.cs @@ -3,6 +3,8 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Caching.Distributed; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; using Nito.AsyncEx; using Volo.Abp.MultiTenancy; @@ -14,6 +16,8 @@ namespace Volo.Abp.Caching public class DistributedCache : IDistributedCache where TCacheItem : class { + public ILogger> Logger { get; set; } + protected string CacheName { get; set; } protected bool IgnoreMultiTenancy { get; set; } @@ -31,25 +35,49 @@ namespace Volo.Abp.Caching protected DistributedCacheEntryOptions DefaultCacheOptions; private readonly CacheOptions _cacheOption; + + private readonly DistributedCacheOptions _distributedCacheOption; + public DistributedCache( IOptions cacheOption, + IOptions distributedCacheOption, IDistributedCache cache, ICancellationTokenProvider cancellationTokenProvider, + IObjectSerializer objectSerializer, ICurrentTenant currentTenant) { + _distributedCacheOption = distributedCacheOption.Value; _cacheOption = cacheOption.Value; Cache = cache; CancellationTokenProvider = cancellationTokenProvider; + Logger = NullLogger>.Instance; ObjectSerializer = objectSerializer; CurrentTenant = currentTenant; SetDefaultOptions(); } - public virtual TCacheItem Get(string key) + public virtual TCacheItem Get(string key, bool? hideErrors = null) { - var cachedBytes = Cache.Get(NormalizeKey(key)); + hideErrors = hideErrors ?? _distributedCacheOption.HideErrors; + + byte[] cachedBytes; + + try + { + cachedBytes = Cache.Get(NormalizeKey(key)); + } + catch (Exception ex) + { + if ((bool) hideErrors) + { + Logger.LogException(ex, LogLevel.Warning); + return null; + } + throw; + } + if (cachedBytes == null) { return null; @@ -58,9 +86,26 @@ namespace Volo.Abp.Caching return ObjectSerializer.Deserialize(cachedBytes); } - public virtual async Task GetAsync(string key, CancellationToken token = default) + public virtual async Task GetAsync(string key, bool? hideErrors = null, CancellationToken token = default) { - var cachedBytes = await Cache.GetAsync(NormalizeKey(key), CancellationTokenProvider.FallbackToProvider(token)); + hideErrors = hideErrors ?? _distributedCacheOption.HideErrors; + + byte[] cachedBytes; + + try + { + cachedBytes = await Cache.GetAsync(NormalizeKey(key), CancellationTokenProvider.FallbackToProvider(token)); + } + catch (Exception ex) + { + if ((bool)hideErrors) + { + Logger.LogException(ex, LogLevel.Warning); + return null; + } + throw; + } + if (cachedBytes == null) { return null; @@ -72,9 +117,10 @@ namespace Volo.Abp.Caching public TCacheItem GetOrAdd( string key, Func factory, - Func optionsFactory = null) + Func optionsFactory = null, + bool? hideErrors = null) { - var value = Get(key); + var value = Get(key, hideErrors); if (value != null) { return value; @@ -82,14 +128,14 @@ namespace Volo.Abp.Caching using (AsyncLock.Lock()) { - value = Get(key); + value = Get(key, hideErrors); if (value != null) { return value; } value = factory(); - Set(key, value, optionsFactory?.Invoke()); + Set(key, value, optionsFactory?.Invoke(), hideErrors); } return value; @@ -99,10 +145,11 @@ namespace Volo.Abp.Caching string key, Func> factory, Func optionsFactory = null, + bool? hideErrors = null, CancellationToken token = default) { token = CancellationTokenProvider.FallbackToProvider(token); - var value = await GetAsync(key, token); + var value = await GetAsync(key, hideErrors, token); if (value != null) { return value; @@ -110,56 +157,142 @@ namespace Volo.Abp.Caching using (await AsyncLock.LockAsync(token)) { - value = await GetAsync(key, token); + value = await GetAsync(key, hideErrors, token); if (value != null) { return value; } value = await factory(); - await SetAsync(key, value, optionsFactory?.Invoke(), token); + await SetAsync(key, value, optionsFactory?.Invoke(), hideErrors, token); } return value; } - public virtual void Set(string key, TCacheItem value, DistributedCacheEntryOptions options = null) + public virtual void Set(string key, TCacheItem value, DistributedCacheEntryOptions options = null, bool? hideErrors = null) { - Cache.Set( - NormalizeKey(key), - ObjectSerializer.Serialize(value), - options ?? DefaultCacheOptions - ); + hideErrors = hideErrors ?? _distributedCacheOption.HideErrors; + + try + { + Cache.Set( + NormalizeKey(key), + ObjectSerializer.Serialize(value), + options ?? DefaultCacheOptions + ); + } + catch (Exception ex) + { + if ((bool) hideErrors) + { + Logger.LogException(ex, LogLevel.Warning); + return; + } + + throw; + } } - public virtual Task SetAsync(string key, TCacheItem value, DistributedCacheEntryOptions options = null, CancellationToken token = default) + public virtual Task SetAsync(string key, TCacheItem value, DistributedCacheEntryOptions options = null, bool? hideErrors = null, CancellationToken token = default) { - return Cache.SetAsync( - NormalizeKey(key), - ObjectSerializer.Serialize(value), - options ?? DefaultCacheOptions, - CancellationTokenProvider.FallbackToProvider(token) - ); + hideErrors = hideErrors ?? _distributedCacheOption.HideErrors; + + try + { + return Cache.SetAsync( + NormalizeKey(key), + ObjectSerializer.Serialize(value), + options ?? DefaultCacheOptions, + CancellationTokenProvider.FallbackToProvider(token) + ); + } + catch (Exception ex) + { + if ((bool)hideErrors) + { + Logger.LogException(ex, LogLevel.Warning); + return Task.CompletedTask; + } + throw; + } } - public virtual void Refresh(string key) + public virtual void Refresh(string key, bool? hideErrors = null) { - Cache.Refresh(NormalizeKey(key)); + hideErrors = hideErrors ?? _distributedCacheOption.HideErrors; + + try + { + Cache.Refresh(NormalizeKey(key)); + } + catch (Exception ex) + { + if ((bool) hideErrors) + { + Logger.LogException(ex, LogLevel.Warning); + return; + } + + throw; + } } - public virtual Task RefreshAsync(string key, CancellationToken token = default) + public virtual Task RefreshAsync(string key, bool? hideErrors = null, CancellationToken token = default) { - return Cache.RefreshAsync(NormalizeKey(key), CancellationTokenProvider.FallbackToProvider(token)); + hideErrors = hideErrors ?? _distributedCacheOption.HideErrors; + + try + { + return Cache.RefreshAsync(NormalizeKey(key), CancellationTokenProvider.FallbackToProvider(token)); + } + catch (Exception ex) + { + if ((bool)hideErrors) + { + Logger.LogException(ex, LogLevel.Warning); + return Task.CompletedTask; + } + throw; + } } - public virtual void Remove(string key) + public virtual void Remove(string key, bool? hideErrors = null) { - Cache.Remove(NormalizeKey(key)); + hideErrors = hideErrors ?? _distributedCacheOption.HideErrors; + + try + { + Cache.Remove(NormalizeKey(key)); + } + catch (Exception ex) + { + if ((bool) hideErrors) + { + Logger.LogException(ex, LogLevel.Warning); + } + + throw; + } } - public virtual Task RemoveAsync(string key, CancellationToken token = default) + public virtual Task RemoveAsync(string key, bool? hideErrors = null, CancellationToken token = default) { - return Cache.RemoveAsync(NormalizeKey(key), CancellationTokenProvider.FallbackToProvider(token)); + hideErrors = hideErrors ?? _distributedCacheOption.HideErrors; + + try + { + return Cache.RemoveAsync(NormalizeKey(key), CancellationTokenProvider.FallbackToProvider(token)); + } + catch (Exception ex) + { + if ((bool)hideErrors) + { + Logger.LogException(ex, LogLevel.Warning); + return Task.CompletedTask; + } + throw; + } } protected virtual string NormalizeKey(string key) @@ -173,6 +306,7 @@ namespace Volo.Abp.Caching return normalizedKey; } + protected virtual DistributedCacheEntryOptions GetDefaultCacheEntryOptions() { foreach (var configure in _cacheOption.CacheConfigurators) diff --git a/framework/src/Volo.Abp.Caching/Volo/Abp/Caching/DistributedCacheOptions.cs b/framework/src/Volo.Abp.Caching/Volo/Abp/Caching/DistributedCacheOptions.cs new file mode 100644 index 0000000000..36a465ebaa --- /dev/null +++ b/framework/src/Volo.Abp.Caching/Volo/Abp/Caching/DistributedCacheOptions.cs @@ -0,0 +1,10 @@ +namespace Volo.Abp.Caching +{ + public class DistributedCacheOptions + { + /// + /// Throw or hide exceptions for the distributed cache. + /// + public bool HideErrors { get; set; } = true; + } +} diff --git a/framework/src/Volo.Abp.Caching/Volo/Abp/Caching/IDistributedCache.cs b/framework/src/Volo.Abp.Caching/Volo/Abp/Caching/IDistributedCache.cs index 1e21d3a3a6..1567bfca30 100644 --- a/framework/src/Volo.Abp.Caching/Volo/Abp/Caching/IDistributedCache.cs +++ b/framework/src/Volo.Abp.Caching/Volo/Abp/Caching/IDistributedCache.cs @@ -10,55 +10,65 @@ namespace Volo.Abp.Caching where TCacheItem : class { TCacheItem Get( - string key + string key, + bool? hideErrors = null ); Task GetAsync( [NotNull] string key, + bool? hideErrors = null, CancellationToken token = default ); TCacheItem GetOrAdd( string key, Func factory, - Func optionsFactory = null + Func optionsFactory = null, + bool? hideErrors = null ); Task GetOrAddAsync( [NotNull] string key, Func> factory, Func optionsFactory = null, + bool? hideErrors = null, CancellationToken token = default ); void Set( string key, TCacheItem value, - DistributedCacheEntryOptions options = null + DistributedCacheEntryOptions options = null, + bool? hideErrors = null ); Task SetAsync( [NotNull] string key, [NotNull] TCacheItem value, [CanBeNull] DistributedCacheEntryOptions options = null, + bool? hideErrors = null, CancellationToken token = default ); void Refresh( - string key + string key, + bool? hideErrors = null ); Task RefreshAsync( string key, + bool? hideErrors = null, CancellationToken token = default ); void Remove( - string key + string key, + bool? hideErrors = null ); Task RemoveAsync( string key, + bool? hideErrors = null, CancellationToken token = default ); }