migrate from MemoryCache.Default to IMemoryCache

This commit is contained in:
Alexey Bannov 2022-05-18 19:07:09 +03:00
parent addf33bf5a
commit cff4f0188b
6 changed files with 63 additions and 23 deletions

View File

@ -43,6 +43,7 @@
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="6.0.4" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Primitives" Version="6.0.0" />
<PackageReference Include="Microsoft.Windows.Compatibility" Version="6.0.0" />
<!-- <PackageReference Include="Microsoft.CodeQuality.Analyzers" Version="2.9.4">
<PrivateAssets>all</PrivateAssets>

View File

@ -24,30 +24,29 @@
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
using Microsoft.Extensions.Primitives;
namespace ASC.Common.Caching;
[Singletone]
public class AscCacheNotify
{
private readonly ICacheNotify<AscCacheItem> _cacheNotify;
private readonly ICache _cache;
public AscCacheNotify(ICacheNotify<AscCacheItem> cacheNotify)
public AscCacheNotify(ICacheNotify<AscCacheItem> cacheNotify, ICache cache)
{
_cacheNotify = cacheNotify;
_cache = cache;
_cacheNotify.Subscribe((item) => { OnClearCache(); }, CacheNotifyAction.Any);
}
public void ClearCache() => _cacheNotify.Publish(new AscCacheItem { Id = Guid.NewGuid().ToString() }, CacheNotifyAction.Any);
public static void OnClearCache()
public void OnClearCache()
{
var keys = MemoryCache.Default.Select(r => r.Key);
foreach (var k in keys)
{
MemoryCache.Default.Remove(k);
}
_cache.Reset();
}
}
@ -56,6 +55,7 @@ public class AscCache : ICache
{
private readonly IMemoryCache _memoryCache;
private readonly ConcurrentDictionary<string, object> _memoryCacheKeys;
private static CancellationTokenSource _resetCacheToken = new CancellationTokenSource();
public AscCache(IMemoryCache memoryCache)
{
@ -72,7 +72,8 @@ public class AscCache : ICache
{
var options = new MemoryCacheEntryOptions()
.SetSlidingExpiration(sligingExpiration)
.RegisterPostEvictionCallback(EvictionCallback);
.RegisterPostEvictionCallback(EvictionCallback)
.AddExpirationToken(new CancellationChangeToken(_resetCacheToken.Token));
_memoryCache.Set(key, value, options);
_memoryCacheKeys.TryAdd(key, null);
@ -82,7 +83,9 @@ public class AscCache : ICache
{
var options = new MemoryCacheEntryOptions()
.SetAbsoluteExpiration(absolutExpiration == DateTime.MaxValue ? DateTimeOffset.MaxValue : new DateTimeOffset(absolutExpiration))
.RegisterPostEvictionCallback(EvictionCallback);
.RegisterPostEvictionCallback(EvictionCallback)
.AddExpirationToken(new CancellationChangeToken(_resetCacheToken.Token));
_memoryCache.Set(key, value, options);
_memoryCacheKeys.TryAdd(key, null);
@ -104,6 +107,17 @@ public class AscCache : ICache
}
}
public void Reset()
{
if (_resetCacheToken != null && !_resetCacheToken.IsCancellationRequested && _resetCacheToken.Token.CanBeCanceled)
{
_resetCacheToken.Cancel();
_resetCacheToken.Dispose();
}
_resetCacheToken = new CancellationTokenSource();
}
public ConcurrentDictionary<string, T> HashGetAll<T>(string key) =>
_memoryCache.GetOrCreate(key, r => new ConcurrentDictionary<string, T>());
@ -120,11 +134,17 @@ public class AscCache : ICache
public void HashSet<T>(string key, string field, T value)
{
var options = new MemoryCacheEntryOptions()
.SetAbsoluteExpiration(DateTime.MaxValue)
.AddExpirationToken(new CancellationChangeToken(_resetCacheToken.Token));
var dic = HashGetAll<T>(key);
if (value != null)
{
dic.AddOrUpdate(field, value, (k, v) => value);
_memoryCache.Set(key, dic, DateTime.MaxValue);
_memoryCache.Set(key, dic, options);
}
else if (dic != null)
{
@ -136,7 +156,7 @@ public class AscCache : ICache
}
else
{
_memoryCache.Set(key, dic, DateTime.MaxValue);
_memoryCache.Set(key, dic, options);
}
}
}

View File

@ -44,4 +44,6 @@ public interface ICache
T HashGet<T>(string key, string field);
void HashSet<T>(string key, string field, T value);
void Reset();
}

View File

@ -30,6 +30,7 @@ public class DBResourceManager : ResourceManager
{
public static readonly bool WhiteLableEnabled;
private readonly ConcurrentDictionary<string, ResourceSet> _resourceSets = new ConcurrentDictionary<string, ResourceSet>();
private readonly IMemoryCache _memoryCache;
public DBResourceManager(string filename, Assembly assembly)
: base(filename, assembly)
@ -37,6 +38,7 @@ public class DBResourceManager : ResourceManager
}
public DBResourceManager(
IMemoryCache memoryCache,
IConfiguration configuration,
IOptionsMonitor<ILog> option,
DbContextManager<ResourceDbContext> dbContext,
@ -44,6 +46,7 @@ public class DBResourceManager : ResourceManager
Assembly assembly)
: base(filename, assembly)
{
_memoryCache = memoryCache;
_configuration = configuration;
_option = option;
_dbContext = dbContext;
@ -118,7 +121,7 @@ public class DBResourceManager : ResourceManager
if (set == null)
{
var invariant = culture == CultureInfo.InvariantCulture ? base.InternalGetResourceSet(CultureInfo.InvariantCulture, true, true) : null;
set = new DBResourceSet(_configuration, _option, _dbContext, invariant, culture, BaseName);
set = new DBResourceSet(_memoryCache, _configuration, _option, _dbContext, invariant, culture, BaseName);
_resourceSets.AddOrUpdate(culture.Name, set, (k, v) => set);
}
@ -131,7 +134,7 @@ public class DBResourceManager : ResourceManager
private readonly TimeSpan _cacheTimeout = TimeSpan.FromMinutes(120); // for performance
private readonly object _locker = new object();
private readonly MemoryCache _cache;
private readonly IMemoryCache _cache;
private readonly ResourceSet _invariant;
private readonly string _culture;
private readonly string _fileName;
@ -139,6 +142,7 @@ public class DBResourceManager : ResourceManager
private readonly DbContextManager<ResourceDbContext> _dbContext;
public DBResourceSet(
IMemoryCache memoryCache,
IConfiguration configuration,
IOptionsMonitor<ILog> option,
DbContextManager<ResourceDbContext> dbContext,
@ -165,7 +169,7 @@ public class DBResourceManager : ResourceManager
_invariant = invariant;
_culture = invariant != null ? NeutralCulture : culture.Name;
_fileName = filename.Split('.').Last() + ".resx";
_cache = MemoryCache.Default;
_cache = memoryCache;
}
public override string GetString(string name, bool ignoreCase)
@ -223,11 +227,21 @@ public class DBResourceManager : ResourceManager
lock (_locker)
{
dic = _cache.Get(key) as Dictionary<string, string>;
if (dic == null)
{
var policy = _cacheTimeout == TimeSpan.Zero ? null : new CacheItemPolicy() { AbsoluteExpiration = DateTimeOffset.Now.Add(_cacheTimeout) };
dic = LoadResourceSet(_fileName, _culture);
_cache.Set(key, dic, policy);
if (_cacheTimeout == TimeSpan.Zero)
{
_cache.Set(key, dic);
}
else
{
_cache.Set(key, dic, DateTimeOffset.Now.Add(_cacheTimeout));
}
}
}
}

View File

@ -141,4 +141,5 @@ global using Telegram.Bot;
global using static ASC.Security.Cryptography.EmailValidationKeyProvider;
global using ASC.Core.Common.Notify.IntegrationEvents.Events;
global using ASC.EventBus.Abstractions;
global using ASC.EventBus.Abstractions;
global using Microsoft.Extensions.Caching.Memory;

View File

@ -53,7 +53,8 @@ namespace ASC.Data.Backup.Services;
[Transient]
public class RestoreProgressItem : BaseBackupProgressItem
{
{
private readonly ICache _cache;
private TenantManager _tenantManager;
private BackupStorageFactory _backupStorageFactory;
private readonly NotifyHelper _notifyHelper;
@ -66,13 +67,14 @@ public class RestoreProgressItem : BaseBackupProgressItem
private Dictionary<string, string> _configPaths;
public RestoreProgressItem(
ILog logger,
ILog logger,
ICache cache,
IServiceScopeFactory serviceScopeFactory,
NotifyHelper notifyHelper,
CoreBaseSettings coreBaseSettings)
: base(logger, serviceScopeFactory)
{
_cache = cache;
_notifyHelper = notifyHelper;
_coreBaseSettings = coreBaseSettings;
@ -154,8 +156,8 @@ public class RestoreProgressItem : BaseBackupProgressItem
Tenant restoredTenant = null;
if (restoreTask.Dump)
{
AscCacheNotify.OnClearCache();
{
_cache.Reset();
if (Notify)
{