Hybrid Cache: Resolve start-up errors with mis-matched types (#20554)
* Be consistent in use of GetOrCreateAsync overload in exists and retrieval.
Ensure nullability of ContentCacheNode is consistent in exists and retrieval.
* Applied suggestion from code review.
* Move seeding to Umbraco application starting rather than started, ensuring an initial request is served.
* Tighten up hybrid cache exists check with locking around check and remove, and use of cancellation token.
(cherry picked from commit 81a8a0c191)
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using Microsoft.Extensions.Caching.Hybrid;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
@@ -33,15 +34,15 @@ public class HybridCacheExtensionsTests
|
||||
_cacheMock
|
||||
.Setup(cache => cache.GetOrCreateAsync(
|
||||
key,
|
||||
null!,
|
||||
It.IsAny<Func<object, CancellationToken, ValueTask<ContentCacheNode>>>(),
|
||||
It.IsAny<Func<CancellationToken, ValueTask<ContentCacheNode?>>>(),
|
||||
It.IsAny<Func<Func<CancellationToken, ValueTask<ContentCacheNode?>>, CancellationToken, ValueTask<ContentCacheNode?>>>(),
|
||||
It.IsAny<HybridCacheEntryOptions>(),
|
||||
null,
|
||||
CancellationToken.None))
|
||||
.ReturnsAsync(expectedValue);
|
||||
|
||||
// Act
|
||||
var exists = await HybridCacheExtensions.ExistsAsync<ContentCacheNode>(_cacheMock.Object, key);
|
||||
var exists = await HybridCacheExtensions.ExistsAsync<ContentCacheNode?>(_cacheMock.Object, key, CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
Assert.IsTrue(exists);
|
||||
@@ -56,24 +57,24 @@ public class HybridCacheExtensionsTests
|
||||
_cacheMock
|
||||
.Setup(cache => cache.GetOrCreateAsync(
|
||||
key,
|
||||
null!,
|
||||
It.IsAny<Func<object, CancellationToken, ValueTask<ContentCacheNode>>>(),
|
||||
It.IsAny<Func<CancellationToken, ValueTask<ContentCacheNode?>>>(),
|
||||
It.IsAny<Func<Func<CancellationToken, ValueTask<ContentCacheNode?>>, CancellationToken, ValueTask<ContentCacheNode?>>>(),
|
||||
It.IsAny<HybridCacheEntryOptions>(),
|
||||
null,
|
||||
CancellationToken.None))
|
||||
.Returns((
|
||||
string key,
|
||||
object? state,
|
||||
Func<object, CancellationToken, ValueTask<ContentCacheNode>> factory,
|
||||
Func<CancellationToken, ValueTask<ContentCacheNode?>> state,
|
||||
Func<Func<CancellationToken, ValueTask<ContentCacheNode?>>, CancellationToken, ValueTask<ContentCacheNode?>> factory,
|
||||
HybridCacheEntryOptions? options,
|
||||
IEnumerable<string>? tags,
|
||||
CancellationToken token) =>
|
||||
{
|
||||
return factory(state!, token);
|
||||
return factory(state, token);
|
||||
});
|
||||
|
||||
// Act
|
||||
var exists = await HybridCacheExtensions.ExistsAsync<ContentCacheNode>(_cacheMock.Object, key);
|
||||
var exists = await HybridCacheExtensions.ExistsAsync<ContentCacheNode?>(_cacheMock.Object, key, CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
Assert.IsFalse(exists);
|
||||
@@ -89,15 +90,15 @@ public class HybridCacheExtensionsTests
|
||||
_cacheMock
|
||||
.Setup(cache => cache.GetOrCreateAsync(
|
||||
key,
|
||||
null!,
|
||||
It.IsAny<Func<object, CancellationToken, ValueTask<string>>>(),
|
||||
It.IsAny<Func<CancellationToken, ValueTask<string>>>(),
|
||||
It.IsAny<Func<Func<CancellationToken, ValueTask<string>>, CancellationToken, ValueTask<string>>>(),
|
||||
It.IsAny<HybridCacheEntryOptions>(),
|
||||
null,
|
||||
CancellationToken.None))
|
||||
.ReturnsAsync(expectedValue);
|
||||
|
||||
// Act
|
||||
var (exists, value) = await HybridCacheExtensions.TryGetValueAsync<string>(_cacheMock.Object, key);
|
||||
var (exists, value) = await HybridCacheExtensions.TryGetValueAsync<string>(_cacheMock.Object, key, CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
Assert.IsTrue(exists);
|
||||
@@ -114,15 +115,15 @@ public class HybridCacheExtensionsTests
|
||||
_cacheMock
|
||||
.Setup(cache => cache.GetOrCreateAsync(
|
||||
key,
|
||||
null!,
|
||||
It.IsAny<Func<object, CancellationToken, ValueTask<int>>>(),
|
||||
It.IsAny<Func<CancellationToken, ValueTask<int>>>(),
|
||||
It.IsAny<Func<Func<CancellationToken, ValueTask<int>>, CancellationToken, ValueTask<int>>>(),
|
||||
It.IsAny<HybridCacheEntryOptions>(),
|
||||
null,
|
||||
CancellationToken.None))
|
||||
.ReturnsAsync(expectedValue);
|
||||
|
||||
// Act
|
||||
var (exists, value) = await HybridCacheExtensions.TryGetValueAsync<int>(_cacheMock.Object, key);
|
||||
var (exists, value) = await HybridCacheExtensions.TryGetValueAsync<int>(_cacheMock.Object, key, CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
Assert.IsTrue(exists);
|
||||
@@ -138,15 +139,15 @@ public class HybridCacheExtensionsTests
|
||||
_cacheMock
|
||||
.Setup(cache => cache.GetOrCreateAsync(
|
||||
key,
|
||||
null!,
|
||||
It.IsAny<Func<object, CancellationToken, ValueTask<object>>>(),
|
||||
It.IsAny<Func<CancellationToken, ValueTask<object>>>(),
|
||||
It.IsAny<Func<Func<CancellationToken, ValueTask<object>>, CancellationToken, ValueTask<object>>>(),
|
||||
It.IsAny<HybridCacheEntryOptions>(),
|
||||
null,
|
||||
CancellationToken.None))
|
||||
.ReturnsAsync(null!);
|
||||
|
||||
// Act
|
||||
var (exists, value) = await HybridCacheExtensions.TryGetValueAsync<int?>(_cacheMock.Object, key);
|
||||
var (exists, value) = await HybridCacheExtensions.TryGetValueAsync<int?>(_cacheMock.Object, key, CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
Assert.IsTrue(exists);
|
||||
@@ -160,16 +161,16 @@ public class HybridCacheExtensionsTests
|
||||
string key = "test-key";
|
||||
|
||||
_cacheMock.Setup(cache => cache.GetOrCreateAsync(
|
||||
key,
|
||||
null,
|
||||
It.IsAny<Func<object?, CancellationToken, ValueTask<string>>>(),
|
||||
It.IsAny<HybridCacheEntryOptions>(),
|
||||
null,
|
||||
CancellationToken.None))
|
||||
key,
|
||||
It.IsAny<Func<CancellationToken, ValueTask<object>>>(),
|
||||
It.IsAny<Func<Func<CancellationToken, ValueTask<object>>, CancellationToken, ValueTask<object>>>(),
|
||||
It.IsAny<HybridCacheEntryOptions>(),
|
||||
null,
|
||||
CancellationToken.None))
|
||||
.Returns((
|
||||
string key,
|
||||
object? state,
|
||||
Func<object?, CancellationToken, ValueTask<string>> factory,
|
||||
Func<CancellationToken, ValueTask<object>> state,
|
||||
Func<Func<CancellationToken, ValueTask<object>>, CancellationToken, ValueTask<object>> factory,
|
||||
HybridCacheEntryOptions? options,
|
||||
IEnumerable<string>? tags,
|
||||
CancellationToken token) =>
|
||||
@@ -178,7 +179,7 @@ public class HybridCacheExtensionsTests
|
||||
});
|
||||
|
||||
// Act
|
||||
var (exists, value) = await HybridCacheExtensions.TryGetValueAsync<string>(_cacheMock.Object, key);
|
||||
var (exists, value) = await HybridCacheExtensions.TryGetValueAsync<object>(_cacheMock.Object, key, CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
Assert.IsFalse(exists);
|
||||
|
||||
Reference in New Issue
Block a user