111 lines
4.3 KiB
C#
111 lines
4.3 KiB
C#
using adas_core.Application.Services.Interfaces;
|
|
using adas_core.Domain.Enums;
|
|
using adas_core.Domain.Models.AppSettings;
|
|
using adas_core.Domain.Models.GroupedObservations;
|
|
using adas_core.Domain.Utils;
|
|
using MongoDB.Bson;
|
|
|
|
namespace adas_core.Application.Services.Caching
|
|
{
|
|
/// <summary>
|
|
/// Orquestador de caché. Selecciona el backend (Redis, InMemory, None)
|
|
/// según CacheSettings y la entidad del key.
|
|
/// Implementa ICacheService y delega en el backend elegido.
|
|
/// </summary>
|
|
public class CacheDispatcher(
|
|
RedisService redis,
|
|
CacheService memory,
|
|
NoCacheService noop,
|
|
CacheSettings cacheSettings)
|
|
: ICacheService
|
|
{
|
|
|
|
// Selección de backend
|
|
private ICacheService SelectBackend(string key)
|
|
{
|
|
var entity = CacheKeyClassifier.Classify(key);
|
|
var mode = entity switch
|
|
{
|
|
CacheEnum.EntityType.Patients => cacheSettings.Patients,
|
|
CacheEnum.EntityType.Displays => cacheSettings.Displays,
|
|
CacheEnum.EntityType.PumpObservations => cacheSettings.PumpObservations,
|
|
CacheEnum.EntityType.Appointments => cacheSettings.Appointments,
|
|
CacheEnum.EntityType.GroupedObservations => cacheSettings.GroupedObservations,
|
|
_ => CacheEnum.Mode.Cache
|
|
};
|
|
|
|
return mode switch
|
|
{
|
|
CacheEnum.Mode.Redis => redis,
|
|
CacheEnum.Mode.Cache => memory,
|
|
_ => noop
|
|
};
|
|
}
|
|
|
|
// Para GroupedObservations generamos la misma clave compuesta que el resto de servicios,
|
|
// de modo que el clasificador y la política de TTL funcionen igual.
|
|
private static string BuildGroupedKey(GroupedField gf, ObjectId patientId)
|
|
=> $"GroupedObs:{patientId}:{gf.Name}";
|
|
|
|
private ICacheService SelectBackend(GroupedField groupedField, ObjectId patientId)
|
|
=> SelectBackend(BuildGroupedKey(groupedField, patientId));
|
|
|
|
|
|
// GetOrSet (KEY string)
|
|
public Task<T> GetOrSetObjectAsync<T>(
|
|
string key,
|
|
Func<Task<T>> factory,
|
|
TimeSpan? ttl = null,
|
|
CancellationToken cancellationToken = default)
|
|
=> SelectBackend(key).GetOrSetObjectAsync(key, factory, ttl, cancellationToken);
|
|
|
|
public Task<string?> GetOrSetValueAsync(
|
|
string key,
|
|
Func<Task<string>> loader,
|
|
TimeSpan? ttl = null)
|
|
=> SelectBackend(key).GetOrSetValueAsync(key, loader, ttl);
|
|
|
|
|
|
// GetOrSet (GroupedField + PatientId)
|
|
public Task<T> GetOrSetObjectAsync<T>(
|
|
GroupedField groupedField,
|
|
ObjectId patientId,
|
|
Func<Task<T>> factory,
|
|
TimeSpan? ttl = null,
|
|
CancellationToken cancellationToken = default)
|
|
=> SelectBackend(groupedField, patientId)
|
|
.GetOrSetObjectAsync(groupedField, patientId, factory, ttl, cancellationToken);
|
|
|
|
|
|
// Set/Get básicos
|
|
public void SetValue(string key, string value)
|
|
=> SelectBackend(key).SetValue(key, value);
|
|
|
|
public string? GetValue(string key)
|
|
=> SelectBackend(key).GetValue(key);
|
|
|
|
public Task<T?> GetObjectAsync<T>(string key, bool upd = true)
|
|
=> SelectBackend(key).GetObjectAsync<T>(key, upd);
|
|
|
|
public Task SetObjectAsync<T>(string key, T obj, bool upd = true)
|
|
=> SelectBackend(key).SetObjectAsync(key, obj, upd);
|
|
|
|
public Task<T?> GetObjectAsync<T>(string key, TimeSpan? ttl, bool upd)
|
|
=> SelectBackend(key).GetObjectAsync<T>(key, ttl, upd);
|
|
|
|
public Task SetObjectAsync<T>(string key, T obj, TimeSpan? ttl, bool upd)
|
|
=> SelectBackend(key).SetObjectAsync(key, obj, ttl, upd);
|
|
|
|
public Task DeleteObjectAsync(string key)
|
|
=> SelectBackend(key).DeleteObjectAsync(key);
|
|
|
|
public async Task<long> DeleteByPatternAsync(string pattern)
|
|
=> await redis.DeleteByPatternAsync(pattern) + await memory.DeleteByPatternAsync(pattern);
|
|
|
|
public void CleanCache()
|
|
{
|
|
memory.CleanCache();
|
|
redis.CleanCache();
|
|
}
|
|
}
|
|
} |