Browse Source

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

Resolved #762 Distributed Cache should be fault tolerant
pull/766/head
Halil İbrahim Kalkan 8 years ago
committed by GitHub
parent
commit
04fc251ce7
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      framework/src/Volo.Abp.Caching/Volo/Abp/Caching/CacheOptions.cs
  2. 198
      framework/src/Volo.Abp.Caching/Volo/Abp/Caching/DistributedCache.cs
  3. 10
      framework/src/Volo.Abp.Caching/Volo/Abp/Caching/DistributedCacheOptions.cs
  4. 20
      framework/src/Volo.Abp.Caching/Volo/Abp/Caching/IDistributedCache.cs

1
framework/src/Volo.Abp.Caching/Volo/Abp/Caching/CacheOptions.cs

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

198
framework/src/Volo.Abp.Caching/Volo/Abp/Caching/DistributedCache.cs

@ -3,6 +3,8 @@ using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Nito.AsyncEx; using Nito.AsyncEx;
using Volo.Abp.MultiTenancy; using Volo.Abp.MultiTenancy;
@ -14,6 +16,8 @@ namespace Volo.Abp.Caching
public class DistributedCache<TCacheItem> : IDistributedCache<TCacheItem> public class DistributedCache<TCacheItem> : IDistributedCache<TCacheItem>
where TCacheItem : class where TCacheItem : class
{ {
public ILogger<DistributedCache<TCacheItem>> Logger { get; set; }
protected string CacheName { get; set; } protected string CacheName { get; set; }
protected bool IgnoreMultiTenancy { get; set; } protected bool IgnoreMultiTenancy { get; set; }
@ -31,25 +35,49 @@ namespace Volo.Abp.Caching
protected DistributedCacheEntryOptions DefaultCacheOptions; protected DistributedCacheEntryOptions DefaultCacheOptions;
private readonly CacheOptions _cacheOption; private readonly CacheOptions _cacheOption;
private readonly DistributedCacheOptions _distributedCacheOption;
public DistributedCache( public DistributedCache(
IOptions<CacheOptions> cacheOption, IOptions<CacheOptions> cacheOption,
IOptions<DistributedCacheOptions> distributedCacheOption,
IDistributedCache cache, IDistributedCache cache,
ICancellationTokenProvider cancellationTokenProvider, ICancellationTokenProvider cancellationTokenProvider,
IObjectSerializer objectSerializer, IObjectSerializer objectSerializer,
ICurrentTenant currentTenant) ICurrentTenant currentTenant)
{ {
_distributedCacheOption = distributedCacheOption.Value;
_cacheOption = cacheOption.Value; _cacheOption = cacheOption.Value;
Cache = cache; Cache = cache;
CancellationTokenProvider = cancellationTokenProvider; CancellationTokenProvider = cancellationTokenProvider;
Logger = NullLogger<DistributedCache<TCacheItem>>.Instance;
ObjectSerializer = objectSerializer; ObjectSerializer = objectSerializer;
CurrentTenant = currentTenant; CurrentTenant = currentTenant;
SetDefaultOptions(); 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) if (cachedBytes == null)
{ {
return null; return null;
@ -58,9 +86,26 @@ namespace Volo.Abp.Caching
return ObjectSerializer.Deserialize<TCacheItem>(cachedBytes); 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) if (cachedBytes == null)
{ {
return null; return null;
@ -72,9 +117,10 @@ namespace Volo.Abp.Caching
public TCacheItem GetOrAdd( public TCacheItem GetOrAdd(
string key, string key,
Func<TCacheItem> factory, 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) if (value != null)
{ {
return value; return value;
@ -82,14 +128,14 @@ namespace Volo.Abp.Caching
using (AsyncLock.Lock()) using (AsyncLock.Lock())
{ {
value = Get(key); value = Get(key, hideErrors);
if (value != null) if (value != null)
{ {
return value; return value;
} }
value = factory(); value = factory();
Set(key, value, optionsFactory?.Invoke()); Set(key, value, optionsFactory?.Invoke(), hideErrors);
} }
return value; return value;
@ -99,10 +145,11 @@ namespace Volo.Abp.Caching
string key, string key,
Func<Task<TCacheItem>> factory, Func<Task<TCacheItem>> factory,
Func<DistributedCacheEntryOptions> optionsFactory = null, Func<DistributedCacheEntryOptions> optionsFactory = null,
bool? hideErrors = null,
CancellationToken token = default) CancellationToken token = default)
{ {
token = CancellationTokenProvider.FallbackToProvider(token); token = CancellationTokenProvider.FallbackToProvider(token);
var value = await GetAsync(key, token); var value = await GetAsync(key, hideErrors, token);
if (value != null) if (value != null)
{ {
return value; return value;
@ -110,56 +157,142 @@ namespace Volo.Abp.Caching
using (await AsyncLock.LockAsync(token)) using (await AsyncLock.LockAsync(token))
{ {
value = await GetAsync(key, token); value = await GetAsync(key, hideErrors, token);
if (value != null) if (value != null)
{ {
return value; return value;
} }
value = await factory(); value = await factory();
await SetAsync(key, value, optionsFactory?.Invoke(), token); await SetAsync(key, value, optionsFactory?.Invoke(), hideErrors, token);
} }
return value; 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( hideErrors = hideErrors ?? _distributedCacheOption.HideErrors;
NormalizeKey(key),
ObjectSerializer.Serialize(value), try
options ?? DefaultCacheOptions {
); 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( hideErrors = hideErrors ?? _distributedCacheOption.HideErrors;
NormalizeKey(key),
ObjectSerializer.Serialize(value), try
options ?? DefaultCacheOptions, {
CancellationTokenProvider.FallbackToProvider(token) 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) protected virtual string NormalizeKey(string key)
@ -173,6 +306,7 @@ namespace Volo.Abp.Caching
return normalizedKey; return normalizedKey;
} }
protected virtual DistributedCacheEntryOptions GetDefaultCacheEntryOptions() protected virtual DistributedCacheEntryOptions GetDefaultCacheEntryOptions()
{ {
foreach (var configure in _cacheOption.CacheConfigurators) foreach (var configure in _cacheOption.CacheConfigurators)

10
framework/src/Volo.Abp.Caching/Volo/Abp/Caching/DistributedCacheOptions.cs

@ -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;
}
}

20
framework/src/Volo.Abp.Caching/Volo/Abp/Caching/IDistributedCache.cs

@ -10,55 +10,65 @@ namespace Volo.Abp.Caching
where TCacheItem : class where TCacheItem : class
{ {
TCacheItem Get( TCacheItem Get(
string key string key,
bool? hideErrors = null
); );
Task<TCacheItem> GetAsync( Task<TCacheItem> GetAsync(
[NotNull] string key, [NotNull] string key,
bool? hideErrors = null,
CancellationToken token = default CancellationToken token = default
); );
TCacheItem GetOrAdd( TCacheItem GetOrAdd(
string key, string key,
Func<TCacheItem> factory, Func<TCacheItem> factory,
Func<DistributedCacheEntryOptions> optionsFactory = null Func<DistributedCacheEntryOptions> optionsFactory = null,
bool? hideErrors = null
); );
Task<TCacheItem> GetOrAddAsync( Task<TCacheItem> GetOrAddAsync(
[NotNull] string key, [NotNull] string key,
Func<Task<TCacheItem>> factory, Func<Task<TCacheItem>> factory,
Func<DistributedCacheEntryOptions> optionsFactory = null, Func<DistributedCacheEntryOptions> optionsFactory = null,
bool? hideErrors = null,
CancellationToken token = default CancellationToken token = default
); );
void Set( void Set(
string key, string key,
TCacheItem value, TCacheItem value,
DistributedCacheEntryOptions options = null DistributedCacheEntryOptions options = null,
bool? hideErrors = null
); );
Task SetAsync( Task SetAsync(
[NotNull] string key, [NotNull] string key,
[NotNull] TCacheItem value, [NotNull] TCacheItem value,
[CanBeNull] DistributedCacheEntryOptions options = null, [CanBeNull] DistributedCacheEntryOptions options = null,
bool? hideErrors = null,
CancellationToken token = default CancellationToken token = default
); );
void Refresh( void Refresh(
string key string key,
bool? hideErrors = null
); );
Task RefreshAsync( Task RefreshAsync(
string key, string key,
bool? hideErrors = null,
CancellationToken token = default CancellationToken token = default
); );
void Remove( void Remove(
string key string key,
bool? hideErrors = null
); );
Task RemoveAsync( Task RemoveAsync(
string key, string key,
bool? hideErrors = null,
CancellationToken token = default CancellationToken token = default
); );
} }

Loading…
Cancel
Save