Merge pull request #765 from abpframework/Distributed-Cache-fault-tolerant

Resolved #762 Distributed Cache should be fault tolerant
pull/766/head
Halil İbrahim Kalkan 7 years ago committed by GitHub
commit 04fc251ce7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,7 +1,6 @@
using Microsoft.Extensions.Caching.Distributed;
using System;
using System.Collections.Generic;
using System.Text;
namespace Volo.Abp.Caching
{

@ -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<TCacheItem> : IDistributedCache<TCacheItem>
where TCacheItem : class
{
public ILogger<DistributedCache<TCacheItem>> 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<CacheOptions> cacheOption,
IOptions<DistributedCacheOptions> distributedCacheOption,
IDistributedCache cache,
ICancellationTokenProvider cancellationTokenProvider,
IObjectSerializer objectSerializer,
ICurrentTenant currentTenant)
{
_distributedCacheOption = distributedCacheOption.Value;
_cacheOption = cacheOption.Value;
Cache = cache;
CancellationTokenProvider = cancellationTokenProvider;
Logger = NullLogger<DistributedCache<TCacheItem>>.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<TCacheItem>(cachedBytes);
}
public virtual async Task<TCacheItem> GetAsync(string key, CancellationToken token = default)
public virtual async Task<TCacheItem> 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<TCacheItem> factory,
Func<DistributedCacheEntryOptions> optionsFactory = null)
Func<DistributedCacheEntryOptions> 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<Task<TCacheItem>> factory,
Func<DistributedCacheEntryOptions> 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)

@ -0,0 +1,10 @@
namespace Volo.Abp.Caching
{
public class DistributedCacheOptions
{
/// <summary>
/// Throw or hide exceptions for the distributed cache.
/// </summary>
public bool HideErrors { get; set; } = true;
}
}

@ -10,55 +10,65 @@ namespace Volo.Abp.Caching
where TCacheItem : class
{
TCacheItem Get(
string key
string key,
bool? hideErrors = null
);
Task<TCacheItem> GetAsync(
[NotNull] string key,
bool? hideErrors = null,
CancellationToken token = default
);
TCacheItem GetOrAdd(
string key,
Func<TCacheItem> factory,
Func<DistributedCacheEntryOptions> optionsFactory = null
Func<DistributedCacheEntryOptions> optionsFactory = null,
bool? hideErrors = null
);
Task<TCacheItem> GetOrAddAsync(
[NotNull] string key,
Func<Task<TCacheItem>> factory,
Func<DistributedCacheEntryOptions> 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
);
}

Loading…
Cancel
Save