Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion RedisBackedHzCache/RedisBackedHzCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ public void Set<T>(string key, T value, TimeSpan ttl)
public T GetOrSet<T>(string key, Func<string, T> valueFactory, TimeSpan ttl, long maxMsToWaitForFactory = 10000)
{
var value = hzCache.Get<T>(key);
if (value != null)
if (!HzMemoryCache.IsNullOrDefault(value))
{
return value;
}
Expand Down
10 changes: 5 additions & 5 deletions RedisBackedHzCache/RedisBackedHzCacheAsync.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,24 +57,24 @@ public Task SetAsync<T>(string key, T value, TimeSpan ttl)

public async Task<T> GetOrSetAsync<T>(string key, Func<string, Task<T>> valueFactory, TimeSpan ttl, long maxMsToWaitForFactory = 10000)
{
var value = await hzCache.GetAsync<T>(key);
if (value != null)
var value = await hzCache.GetAsync<T>(key).ConfigureAwait(false);
if (!HzMemoryCache.IsNullOrDefault(value))
{
Comment thread
JoelNygren-Norce marked this conversation as resolved.
return value;
}

if (options.useRedisAs2ndLevelCache)
{
var redisValue = await GetRedisValueAsync(key);
var redisValue = await GetRedisValueAsync(key).ConfigureAwait(false);
if (!redisValue.IsNull)
{
var ttlValue = await TTLValue.FromRedisValueAsync<T>(Encoding.ASCII.GetBytes(redisValue.ToString()));
var ttlValue = await TTLValue.FromRedisValueAsync<T>(Encoding.ASCII.GetBytes(redisValue.ToString())).ConfigureAwait(false);
hzCache.SetRaw(key, ttlValue);
return (T)ttlValue.value;
}
}

return await hzCache.GetOrSetAsync(key, valueFactory, ttl, maxMsToWaitForFactory);
return await hzCache.GetOrSetAsync(key, valueFactory, ttl, maxMsToWaitForFactory).ConfigureAwait(false);
}

public Task<IList<T>> GetOrSetBatchAsync<T>(IList<string> keys, Func<IList<string>, Task<List<KeyValuePair<string, T>>>> valueFactory)
Expand Down
65 changes: 65 additions & 0 deletions UnitTests/IntegrationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,71 @@ public async Task TestRedisGetOrSet()
}


[TestMethod]
[TestCategory("Integration")]
public async Task TestRedisGetOrSet_ValueType_CallsFactory()
{
// Arrange
var c1 = new RedisBackedHzCache(
new RedisBackedHzCacheOptions { redisConnectionString = ConnectionString, applicationCachePrefix = "test", instanceId = "c1", useRedisAs2ndLevelCache = false });
var factoryCalled = false;

// Act
var result = c1.GetOrSet("int-key", _ =>
{
factoryCalled = true;
return 42;
}, TimeSpan.FromMinutes(1));

// Assert
Assert.IsTrue(factoryCalled, "Factory should be called on cache miss for value types");
Assert.AreEqual(42, result);
await c1.RemoveAsync("int-key");
}
Comment thread
JoelNygren-Norce marked this conversation as resolved.

[TestMethod]
[TestCategory("Integration")]
public async Task TestRedisGetOrSetAsync_ValueType_CallsFactory()
{
// Arrange
var c1 = new RedisBackedHzCache(
new RedisBackedHzCacheOptions { redisConnectionString = ConnectionString, applicationCachePrefix = "test", instanceId = "c1", useRedisAs2ndLevelCache = false });
var factoryCalled = false;

// Act
var result = await c1.GetOrSetAsync("int-key-async", _ =>
{
factoryCalled = true;
return Task.FromResult(42);
}, TimeSpan.FromMinutes(1));

// Assert
Assert.IsTrue(factoryCalled, "Factory should be called on cache miss for value types");
Assert.AreEqual(42, result);
await c1.RemoveAsync("int-key-async");
}
Comment thread
JoelNygren-Norce marked this conversation as resolved.

[TestMethod]
[TestCategory("Integration")]
public async Task TestRedisGetOrSetAsync_ValueType_ReturnsCachedValue()
{
// Arrange
var c1 = new RedisBackedHzCache(
new RedisBackedHzCacheOptions { redisConnectionString = ConnectionString, applicationCachePrefix = "test", instanceId = "c1", useRedisAs2ndLevelCache = false });
await c1.GetOrSetAsync("int-cached", _ => Task.FromResult(42), TimeSpan.FromMinutes(1));

// Act — second call should return cached value, not call factory
var result = await c1.GetOrSetAsync("int-cached", _ =>
{
Assert.Fail("Factory should not be called when value is already cached");
return Task.FromResult(0);
}, TimeSpan.FromMinutes(1));

// Assert
Assert.AreEqual(42, result);
await c1.RemoveAsync("int-cached");
}
Comment thread
JoelNygren-Norce marked this conversation as resolved.

[TestMethod]
[TestCategory("Integration")]
public async Task TestRedisBackplaneDelete()
Expand Down
Loading