|
|
|
@ -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)
|
|
|
|
|