diff --git a/RedisBackedHzCache/RedisBackedHzCache.cs b/RedisBackedHzCache/RedisBackedHzCache.cs index dbd7cd2..fa6c6f3 100644 --- a/RedisBackedHzCache/RedisBackedHzCache.cs +++ b/RedisBackedHzCache/RedisBackedHzCache.cs @@ -219,6 +219,23 @@ public void Set(string key, T value, TimeSpan ttl) public T GetOrSet(string key, Func valueFactory, TimeSpan ttl, long maxMsToWaitForFactory = 10000) { + var value = hzCache.Get(key); + if (value != null) + { + return value; + } + + if (options.useRedisAs2ndLevelCache) + { + var redisValue = GetRedisValue(key); + if (!redisValue.IsNull) + { + var ttlValue = TTLValue.FromRedisValue(Encoding.ASCII.GetBytes(redisValue.ToString())); + hzCache.SetRaw(key, ttlValue); + return (T)ttlValue.value; + } + } + return hzCache.GetOrSet(key, valueFactory, ttl, maxMsToWaitForFactory); } @@ -229,7 +246,8 @@ public IList GetOrSetBatch(IList keys, Func, List GetOrSetBatch(IList keys, Func, List>> valueFactory, TimeSpan ttl) { - using var activity = HzActivities.Source.StartActivityWithCommonTags(HzActivities.Names.GetOrSetBatch, HzActivities.Area.RedisBackedHzCache, key: string.Join(",", keys ?? new List())); + using var activity = HzActivities.Source.StartActivityWithCommonTags(HzActivities.Names.GetOrSetBatch, HzActivities.Area.RedisBackedHzCache, + key: string.Join(",", keys ?? new List())); Func, List>> redisFactory = idList => { // Create a list of redis keys from the list of cache keys diff --git a/RedisBackedHzCache/RedisBackedHzCacheAsync.cs b/RedisBackedHzCache/RedisBackedHzCacheAsync.cs index 880eff6..84c26ce 100644 --- a/RedisBackedHzCache/RedisBackedHzCacheAsync.cs +++ b/RedisBackedHzCache/RedisBackedHzCacheAsync.cs @@ -55,9 +55,26 @@ public Task SetAsync(string key, T value, TimeSpan ttl) return hzCache.SetAsync(key, value, ttl); } - public Task GetOrSetAsync(string key, Func> valueFactory, TimeSpan ttl, long maxMsToWaitForFactory = 10000) + public async Task GetOrSetAsync(string key, Func> valueFactory, TimeSpan ttl, long maxMsToWaitForFactory = 10000) { - return hzCache.GetOrSetAsync(key, valueFactory, ttl, maxMsToWaitForFactory); + var value = await hzCache.GetAsync(key); + if (value != null) + { + return value; + } + + if (options.useRedisAs2ndLevelCache) + { + var redisValue = await GetRedisValueAsync(key); + if (!redisValue.IsNull) + { + var ttlValue = await TTLValue.FromRedisValueAsync(Encoding.ASCII.GetBytes(redisValue.ToString())); + hzCache.SetRaw(key, ttlValue); + return (T)ttlValue.value; + } + } + + return await hzCache.GetOrSetAsync(key, valueFactory, ttl, maxMsToWaitForFactory); } public Task> GetOrSetBatchAsync(IList keys, Func, Task>>> valueFactory) @@ -67,7 +84,8 @@ public Task> GetOrSetBatchAsync(IList keys, Func> GetOrSetBatchAsync(IList keys, Func, Task>>> valueFactory, TimeSpan ttl) { - using var activity = HzActivities.Source.StartActivityWithCommonTags(HzActivities.Names.GetOrSetBatch, HzActivities.Area.RedisBackedHzCache, async: true, key: string.Join(",", keys ?? new List())); + using var activity = HzActivities.Source.StartActivityWithCommonTags(HzActivities.Names.GetOrSetBatch, HzActivities.Area.RedisBackedHzCache, async: true, + key: string.Join(",", keys ?? new List())); Func, Task>>> redisFactory = async idList => { // Create a list of redis keys from the list of cache keys @@ -127,4 +145,4 @@ public Task RemoveAsync(string key) return hzCache.RemoveAsync(key); } } -} +} \ No newline at end of file diff --git a/UnitTests/IntegrationTests.cs b/UnitTests/IntegrationTests.cs index 33d8cb4..c413eaf 100644 --- a/UnitTests/IntegrationTests.cs +++ b/UnitTests/IntegrationTests.cs @@ -298,10 +298,11 @@ public async Task TestRedisGetOrSet() var v1 = c1.GetOrSet("1", _ => new Mocko(10), TimeSpan.FromMinutes(1)); Assert.IsNotNull(v1); Assert.IsTrue(c1.Get("1").num == 10); - await Task.Delay(100); - var c21 = await c2.GetAsync("1"); + await Task.Delay(200); + var c21 = await c2.GetOrSetAsync("1", _ => Task.FromResult(new Mocko(20)), TimeSpan.FromMinutes(1)); Assert.IsTrue(c21.num == 10); Assert.IsTrue(c21.guid != v1.guid); + await c1.RemoveAsync("1"); }