56 lines
2.0 KiB
C#
56 lines
2.0 KiB
C#
using Microsoft.Extensions.Logging;
|
|
using StackExchange.Redis;
|
|
using System.Diagnostics;
|
|
using System.Text.Json;
|
|
|
|
namespace StellaOps.Provcache.Valkey;
|
|
|
|
public sealed partial class ValkeyProvcacheStore
|
|
{
|
|
public async ValueTask<ProvcacheLookupResult> GetAsync(string veriKey, CancellationToken cancellationToken = default)
|
|
{
|
|
var sw = Stopwatch.StartNew();
|
|
cancellationToken.ThrowIfCancellationRequested();
|
|
|
|
try
|
|
{
|
|
var db = await GetDatabaseAsync(cancellationToken).ConfigureAwait(false);
|
|
var redisKey = BuildKey(veriKey);
|
|
|
|
var value = await db.StringGetAsync(redisKey).ConfigureAwait(false);
|
|
sw.Stop();
|
|
|
|
if (value.IsNullOrEmpty)
|
|
{
|
|
_logger.LogDebug("Cache miss for VeriKey {VeriKey} in {ElapsedMs}ms", veriKey, sw.Elapsed.TotalMilliseconds);
|
|
return ProvcacheLookupResult.Miss(sw.Elapsed.TotalMilliseconds);
|
|
}
|
|
|
|
var entry = JsonSerializer.Deserialize<ProvcacheEntry>((string)value!, _jsonOptions);
|
|
if (entry is null)
|
|
{
|
|
_logger.LogWarning("Failed to deserialize cache entry for VeriKey {VeriKey}", veriKey);
|
|
return ProvcacheLookupResult.Miss(sw.Elapsed.TotalMilliseconds);
|
|
}
|
|
|
|
if (_options.SlidingExpiration)
|
|
{
|
|
var ttl = entry.ExpiresAt - _timeProvider.GetUtcNow();
|
|
if (ttl > TimeSpan.Zero)
|
|
{
|
|
await db.KeyExpireAsync(redisKey, ttl).ConfigureAwait(false);
|
|
}
|
|
}
|
|
|
|
_logger.LogDebug("Cache hit for VeriKey {VeriKey} in {ElapsedMs}ms", veriKey, sw.Elapsed.TotalMilliseconds);
|
|
return ProvcacheLookupResult.Hit(entry, ProviderName, sw.Elapsed.TotalMilliseconds);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
sw.Stop();
|
|
_logger.LogError(ex, "Error getting cache entry for VeriKey {VeriKey}", veriKey);
|
|
return ProvcacheLookupResult.Miss(sw.Elapsed.TotalMilliseconds);
|
|
}
|
|
}
|
|
}
|