From 9fa420d29263a41e0b10a522b2e44f6fdddcecc2 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Mon, 28 Jan 2019 14:09:10 +0300 Subject: [PATCH 1/2] Resolved #762 Distributed Cache should be fault tolerant --- .../Volo/Abp/Caching/DistributedCache.cs | 179 ++++++++++++++---- .../Abp/Caching/DistributedCacheOptions.cs | 14 ++ .../Volo/Abp/Caching/IDistributedCache.cs | 20 +- 3 files changed, 176 insertions(+), 37 deletions(-) create mode 100644 framework/src/Volo.Abp.Caching/Volo/Abp/Caching/DistributedCacheOptions.cs 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..0057bfdd94 100644 --- a/framework/src/Volo.Abp.Caching/Volo/Abp/Caching/DistributedCache.cs +++ b/framework/src/Volo.Abp.Caching/Volo/Abp/Caching/DistributedCache.cs @@ -31,13 +31,18 @@ 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; @@ -47,9 +52,25 @@ namespace Volo.Abp.Caching 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) + { + if ((bool) hideErrors) + { + return null; + } + throw; + } + if (cachedBytes == null) { return null; @@ -58,9 +79,25 @@ 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) + { + if ((bool)hideErrors) + { + return null; + } + throw; + } + if (cachedBytes == null) { return null; @@ -72,9 +109,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 +120,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 +137,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 +149,131 @@ 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) + { + if (!(bool) hideErrors) + { + 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) + { + if ((bool)hideErrors) + { + 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) + { + if (!(bool) hideErrors) + { + 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) + { + if ((bool)hideErrors) + { + 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) + { + if (!(bool)hideErrors) + { + 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) + { + if ((bool)hideErrors) + { + return Task.CompletedTask; + } + throw; + } } protected virtual string NormalizeKey(string key) @@ -173,6 +287,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..6912de133f --- /dev/null +++ b/framework/src/Volo.Abp.Caching/Volo/Abp/Caching/DistributedCacheOptions.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Text; + +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 ); } From a715ea551fb80cd519a0f84ae0e13945fef9620d Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Mon, 28 Jan 2019 14:22:35 +0300 Subject: [PATCH 2/2] Added logs to Distrubuted cache --- .../Volo/Abp/Caching/CacheOptions.cs | 1 - .../Volo/Abp/Caching/DistributedCache.cs | 47 +++++++++++++------ .../Abp/Caching/DistributedCacheOptions.cs | 6 +-- 3 files changed, 34 insertions(+), 20 deletions(-) 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 0057bfdd94..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; } @@ -39,6 +43,7 @@ namespace Volo.Abp.Caching IOptions distributedCacheOption, IDistributedCache cache, ICancellationTokenProvider cancellationTokenProvider, + IObjectSerializer objectSerializer, ICurrentTenant currentTenant) { @@ -46,6 +51,7 @@ namespace Volo.Abp.Caching _cacheOption = cacheOption.Value; Cache = cache; CancellationTokenProvider = cancellationTokenProvider; + Logger = NullLogger>.Instance; ObjectSerializer = objectSerializer; CurrentTenant = currentTenant; @@ -62,10 +68,11 @@ namespace Volo.Abp.Caching { cachedBytes = Cache.Get(NormalizeKey(key)); } - catch (Exception) + catch (Exception ex) { if ((bool) hideErrors) { + Logger.LogException(ex, LogLevel.Warning); return null; } throw; @@ -89,10 +96,11 @@ namespace Volo.Abp.Caching { cachedBytes = await Cache.GetAsync(NormalizeKey(key), CancellationTokenProvider.FallbackToProvider(token)); } - catch (Exception) + catch (Exception ex) { if ((bool)hideErrors) { + Logger.LogException(ex, LogLevel.Warning); return null; } throw; @@ -174,12 +182,15 @@ namespace Volo.Abp.Caching options ?? DefaultCacheOptions ); } - catch (Exception) + catch (Exception ex) { - if (!(bool) hideErrors) + if ((bool) hideErrors) { - throw; + Logger.LogException(ex, LogLevel.Warning); + return; } + + throw; } } @@ -196,10 +207,11 @@ namespace Volo.Abp.Caching CancellationTokenProvider.FallbackToProvider(token) ); } - catch (Exception) + catch (Exception ex) { if ((bool)hideErrors) { + Logger.LogException(ex, LogLevel.Warning); return Task.CompletedTask; } throw; @@ -214,12 +226,15 @@ namespace Volo.Abp.Caching { Cache.Refresh(NormalizeKey(key)); } - catch (Exception) + catch (Exception ex) { - if (!(bool) hideErrors) + if ((bool) hideErrors) { - throw; + Logger.LogException(ex, LogLevel.Warning); + return; } + + throw; } } @@ -231,10 +246,11 @@ namespace Volo.Abp.Caching { return Cache.RefreshAsync(NormalizeKey(key), CancellationTokenProvider.FallbackToProvider(token)); } - catch (Exception) + catch (Exception ex) { if ((bool)hideErrors) { + Logger.LogException(ex, LogLevel.Warning); return Task.CompletedTask; } throw; @@ -249,12 +265,14 @@ namespace Volo.Abp.Caching { Cache.Remove(NormalizeKey(key)); } - catch (Exception) + catch (Exception ex) { - if (!(bool)hideErrors) + if ((bool) hideErrors) { - throw; + Logger.LogException(ex, LogLevel.Warning); } + + throw; } } @@ -266,10 +284,11 @@ namespace Volo.Abp.Caching { return Cache.RemoveAsync(NormalizeKey(key), CancellationTokenProvider.FallbackToProvider(token)); } - catch (Exception) + catch (Exception ex) { if ((bool)hideErrors) { + Logger.LogException(ex, LogLevel.Warning); return Task.CompletedTask; } throw; diff --git a/framework/src/Volo.Abp.Caching/Volo/Abp/Caching/DistributedCacheOptions.cs b/framework/src/Volo.Abp.Caching/Volo/Abp/Caching/DistributedCacheOptions.cs index 6912de133f..36a465ebaa 100644 --- a/framework/src/Volo.Abp.Caching/Volo/Abp/Caching/DistributedCacheOptions.cs +++ b/framework/src/Volo.Abp.Caching/Volo/Abp/Caching/DistributedCacheOptions.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Volo.Abp.Caching +namespace Volo.Abp.Caching { public class DistributedCacheOptions {