Hybrid cache: Check for ContentCacheNode instead of object on exists for hybrid cache to ensure correct deserialization (closes #20352) (#20383)

Checked for ContentCacheNode instead of object on exists for hybrid cache to ensure correct deserialization.
This commit is contained in:
Andy Butland
2025-10-06 21:20:16 +02:00
committed by GitHub
parent 4330a99830
commit 184c17e2c8
4 changed files with 13 additions and 12 deletions

View File

@@ -17,9 +17,9 @@ internal static class HybridCacheExtensions
/// Hat-tip: https://github.com/dotnet/aspnetcore/discussions/57191
/// Will never add or alter the state of any items in the cache.
/// </remarks>
public static async Task<bool> ExistsAsync(this Microsoft.Extensions.Caching.Hybrid.HybridCache cache, string key)
public static async Task<bool> ExistsAsync<T>(this Microsoft.Extensions.Caching.Hybrid.HybridCache cache, string key)
{
(bool exists, _) = await TryGetValueAsync<object>(cache, key);
(bool exists, _) = await TryGetValueAsync<T>(cache, key);
return exists;
}

View File

@@ -205,7 +205,7 @@ internal sealed class DocumentCacheService : IDocumentCacheService
var cacheKey = GetCacheKey(key, false);
var existsInCache = await _hybridCache.ExistsAsync(cacheKey);
var existsInCache = await _hybridCache.ExistsAsync<ContentCacheNode>(cacheKey);
if (existsInCache is false)
{
uncachedKeys.Add(key);
@@ -278,7 +278,7 @@ internal sealed class DocumentCacheService : IDocumentCacheService
return false;
}
return await _hybridCache.ExistsAsync(GetCacheKey(keyAttempt.Result, preview));
return await _hybridCache.ExistsAsync<ContentCacheNode>(GetCacheKey(keyAttempt.Result, preview));
}
public async Task RefreshContentAsync(IContent content)

View File

@@ -133,7 +133,7 @@ internal sealed class MediaCacheService : IMediaCacheService
return false;
}
return await _hybridCache.ExistsAsync($"{keyAttempt.Result}");
return await _hybridCache.ExistsAsync<ContentCacheNode>($"{keyAttempt.Result}");
}
public async Task RefreshMediaAsync(IMedia media)
@@ -170,7 +170,7 @@ internal sealed class MediaCacheService : IMediaCacheService
var cacheKey = GetCacheKey(key, false);
var existsInCache = await _hybridCache.ExistsAsync(cacheKey);
var existsInCache = await _hybridCache.ExistsAsync<ContentCacheNode>(cacheKey);
if (existsInCache is false)
{
uncachedKeys.Add(key);

View File

@@ -1,6 +1,7 @@
using Microsoft.Extensions.Caching.Hybrid;
using Moq;
using NUnit.Framework;
using Umbraco.Cms.Infrastructure.HybridCache;
using Umbraco.Cms.Infrastructure.HybridCache.Extensions;
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.PublishedCache.HybridCache.Extensions;
@@ -27,20 +28,20 @@ public class HybridCacheExtensionsTests
{
// Arrange
string key = "test-key";
var expectedValue = "test-value";
var expectedValue = new ContentCacheNode { Id = 1234 };
_cacheMock
.Setup(cache => cache.GetOrCreateAsync(
key,
null!,
It.IsAny<Func<object, CancellationToken, ValueTask<object>>>(),
It.IsAny<Func<object, CancellationToken, ValueTask<ContentCacheNode>>>(),
It.IsAny<HybridCacheEntryOptions>(),
null,
CancellationToken.None))
.ReturnsAsync(expectedValue);
// Act
var exists = await HybridCacheExtensions.ExistsAsync(_cacheMock.Object, key);
var exists = await HybridCacheExtensions.ExistsAsync<ContentCacheNode>(_cacheMock.Object, key);
// Assert
Assert.IsTrue(exists);
@@ -56,14 +57,14 @@ public class HybridCacheExtensionsTests
.Setup(cache => cache.GetOrCreateAsync(
key,
null!,
It.IsAny<Func<object, CancellationToken, ValueTask<object>>>(),
It.IsAny<Func<object, CancellationToken, ValueTask<ContentCacheNode>>>(),
It.IsAny<HybridCacheEntryOptions>(),
null,
CancellationToken.None))
.Returns((
string key,
object? state,
Func<object, CancellationToken, ValueTask<object>> factory,
Func<object, CancellationToken, ValueTask<ContentCacheNode>> factory,
HybridCacheEntryOptions? options,
IEnumerable<string>? tags,
CancellationToken token) =>
@@ -72,7 +73,7 @@ public class HybridCacheExtensionsTests
});
// Act
var exists = await HybridCacheExtensions.ExistsAsync(_cacheMock.Object, key);
var exists = await HybridCacheExtensions.ExistsAsync<ContentCacheNode>(_cacheMock.Object, key);
// Assert
Assert.IsFalse(exists);