refactor cache add perInstanceCache

This commit is contained in:
nick.yi 2025-01-22 11:17:38 +08:00
parent e72a1f1613
commit 84e4b4bf0d
4 changed files with 17 additions and 76 deletions

View file

@ -9,7 +9,6 @@ namespace BotSharp.Abstraction.Infrastructures.Enums
public enum CacheType
{
MemoryCache,
RedisCache,
HybridCache
RedisCache
}
}

View file

@ -11,16 +11,17 @@ public class SharpCacheAttribute : AsyncMoAttribute
public static IServiceProvider Services { get; set; } = null!;
private static readonly object NullMarker = new { __is_null = "$_is_null" };
private int _minutes;
private readonly int _minutes;
private readonly bool _perInstanceCache;
public SharpCacheAttribute(int minutes = 60)
public SharpCacheAttribute(int minutes = 60, bool perInstanceCache = false)
{
_minutes = minutes;
_perInstanceCache = perInstanceCache;
}
public override async ValueTask OnEntryAsync(MethodContext context)
{
var settings = Services.GetRequiredService<SharpCacheSettings>();
if (!settings.Enabled)
{
@ -33,7 +34,7 @@ public class SharpCacheAttribute : AsyncMoAttribute
if (value != null)
{
// check if the cache is out of date
var isOutOfDate = IsOutOfDate(context, value).Result;
var isOutOfDate = await IsOutOfDate(context, value);
if (!isOutOfDate)
{
@ -76,10 +77,19 @@ public class SharpCacheAttribute : AsyncMoAttribute
private string GetCacheKey(SharpCacheSettings settings, MethodContext context)
{
var prefixKey = settings.Prefix + ":" + context.Method.Name;
return $"{prefixKey}_{string.Join("_", context.Arguments.Select(arg => GetCacheKey(arg)))}";
var argsKey = string.Join("_", context.Arguments.Select(arg => GetCacheKeyByArg(arg)));
if (_perInstanceCache && context.Target != null)
{
return $"{prefixKey}-{context.Target.GetHashCode()}_{argsKey}";
}
else
{
return $"{prefixKey}_{argsKey}";
}
}
private string GetCacheKey(object? arg)
private string GetCacheKeyByArg(object? arg)
{
if (arg is null)
{

View file

@ -53,11 +53,9 @@ public static class BotSharpCoreExtensions
services.AddSingleton(x => cacheSettings);
services.AddSingleton<MemoryCacheService>();
services.AddSingleton<RedisCacheService>();
services.AddSingleton<HybridCacheService>();
services.AddSingleton<ICacheService>(sp =>
cacheSettings.CacheType switch
{
CacheType.HybridCache => sp.GetRequiredService<HybridCacheService>(),
CacheType.RedisCache => sp.GetRequiredService<RedisCacheService>(),
_ => sp.GetRequiredService<MemoryCacheService>(),
});

View file

@ -1,66 +0,0 @@
using BotSharp.Abstraction.Infrastructures;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BotSharp.Core.Infrastructures
{
public class HybridCacheService : ICacheService
{
private readonly MemoryCacheService _memoryCache;
private readonly RedisCacheService _redisCache;
public HybridCacheService(
MemoryCacheService memoryCache,
RedisCacheService redisCache)
{
_memoryCache = memoryCache;
_redisCache = redisCache;
}
public async Task<T?> GetAsync<T>(string key)
{
var result = await _memoryCache.GetAsync<T>(key);
if (result != null)
{
return result;
}
result = await _redisCache.GetAsync<T>(key);
if (result != null)
{
await SetAsync(key, result, TimeSpan.FromMinutes(5));
}
return result;
}
public async Task<object> GetAsync(string key, Type type)
{
var result = await _memoryCache.GetAsync(key, type);
if (result != null)
{
return result;
}
result = await _redisCache.GetAsync(key, type);
if (result != null)
{
await SetAsync(key, result, TimeSpan.FromMinutes(5));
}
return result;
}
public async Task SetAsync<T>(string key, T value, TimeSpan? expiry)
{
await _memoryCache.SetAsync(key, value, expiry);
await _redisCache.SetAsync(key, value, expiry);
}
public async Task RemoveAsync(string key)
{
await _memoryCache.RemoveAsync(key);
await _redisCache.RemoveAsync(key);
}
}
}