Implemented hybrid cache for user sessions, api keys and database provided settings. Cleaned up startup and adjusted caching option models for features

This commit is contained in:
2026-02-12 15:29:35 +01:00
parent dd44e5bb86
commit 741a60adc6
19 changed files with 240 additions and 132 deletions

View File

@@ -1,6 +1,6 @@
using System.Text.Json;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Caching.Hybrid;
using Microsoft.Extensions.Options;
using Moonlight.Api.Configuration;
using Moonlight.Api.Database;
@@ -12,18 +12,18 @@ public class SettingsService
{
private readonly DatabaseRepository<SettingsOption> Repository;
private readonly IOptions<SettingsOptions> Options;
private readonly IMemoryCache Cache;
private readonly HybridCache HybridCache;
private const string CacheKey = "Moonlight.Api.SettingsService.{0}";
public SettingsService(
DatabaseRepository<SettingsOption> repository,
IOptions<SettingsOptions> options,
IMemoryCache cache
)
HybridCache hybridCache
)
{
Repository = repository;
Cache = cache;
HybridCache = hybridCache;
Options = options;
}
@@ -31,24 +31,26 @@ public class SettingsService
{
var cacheKey = string.Format(CacheKey, key);
if (Cache.TryGetValue<string>(cacheKey, out var value))
return JsonSerializer.Deserialize<T>(value!);
value = await Repository
.Query()
.Where(x => x.Key == key)
.Select(o => o.ValueJson)
.FirstOrDefaultAsync();
if(string.IsNullOrEmpty(value))
return default;
Cache.Set(
var value = await HybridCache.GetOrCreateAsync<string?>(
cacheKey,
value,
TimeSpan.FromMinutes(Options.Value.CacheMinutes)
async ct =>
{
return await Repository
.Query()
.Where(x => x.Key == key)
.Select(o => o.ValueJson)
.FirstOrDefaultAsync(cancellationToken: ct);
},
new HybridCacheEntryOptions()
{
LocalCacheExpiration = Options.Value.LookupL1CacheTime,
Expiration = Options.Value.LookupL2CacheTime
}
);
if (string.IsNullOrWhiteSpace(value))
return default;
return JsonSerializer.Deserialize<T>(value);
}
@@ -77,7 +79,7 @@ public class SettingsService
await Repository.AddAsync(option);
}
Cache.Remove(cacheKey);
await HybridCache.RemoveAsync(cacheKey);
}
}