Skip to content

Commit

Permalink
Merge pull request #10 from reisenberger/MaxValueFix
Browse files Browse the repository at this point in the history
Handle TimeSpan.MaxValue expiration
  • Loading branch information
reisenberger authored Nov 1, 2017
2 parents 47ec629 + 1af60f3 commit 36b4ecf
Show file tree
Hide file tree
Showing 2 changed files with 140 additions and 4 deletions.
10 changes: 6 additions & 4 deletions src/Polly.Caching.MemoryCache.Shared/MemoryCacheProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,27 +62,29 @@ public object Get(String key)
/// <param name="ttl">The time-to-live for the cache entry.</param>
public void Put(string key, object value, Ttl ttl)
{
TimeSpan remaining = DateTimeOffset.MaxValue - SystemClock.DateTimeOffsetUtcNow();

#if PORTABLE
using (Microsoft.Extensions.Caching.Memory.ICacheEntry entry = _cache.CreateEntry(key)) {
entry.Value = value;
if (ttl.SlidingExpiration)
{
entry.SlidingExpiration = ttl.Timespan;
entry.SlidingExpiration = ttl.Timespan < remaining ? ttl.Timespan : remaining;
}
else
{
entry.AbsoluteExpirationRelativeToNow = ttl.Timespan;
entry.AbsoluteExpirationRelativeToNow = ttl.Timespan < remaining ? ttl.Timespan : remaining;
}
}
#else
System.Runtime.Caching.CacheItemPolicy cacheItemPolicy = new System.Runtime.Caching.CacheItemPolicy();
if (ttl.SlidingExpiration)
{
cacheItemPolicy.SlidingExpiration = ttl.Timespan;
cacheItemPolicy.SlidingExpiration = ttl.Timespan < remaining ? ttl.Timespan : remaining;
}
else
{
cacheItemPolicy.AbsoluteExpiration = SystemClock.DateTimeOffsetUtcNow().Add(ttl.Timespan);
cacheItemPolicy.AbsoluteExpiration = ttl.Timespan < remaining ? SystemClock.DateTimeOffsetUtcNow().Add(ttl.Timespan) : DateTimeOffset.MaxValue;
}
_cache.Set(key, value, cacheItemPolicy);
#endif
Expand Down
134 changes: 134 additions & 0 deletions src/Polly.Caching.MemoryCache.SharedSpecs/MemoryCacheProviderSpecs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,140 @@ public void Put_should_put_item_using_passed_sliding_ttl()
}
}

#region Boundary tests

[Fact]
public void Put_should_put_item_using_passed_nonsliding_ttl_maxvalue()
{
#if PORTABLE
MemoryCacheImplementation memoryCache = new Microsoft.Extensions.Caching.Memory.MemoryCache(new Microsoft.Extensions.Caching.Memory.MemoryCacheOptions());
#else
MemoryCacheImplementation memoryCache = System.Runtime.Caching.MemoryCache.Default;
#endif

string key = "anything";
object value = new object();

MemoryCacheProvider provider = new MemoryCacheProvider(memoryCache);
Ttl ttl = new Ttl(TimeSpan.MaxValue, false);
provider.Put(key, value, ttl);

#if PORTABLE
object got;
memoryCache.TryGetValue(key, out got);
#else
object got = memoryCache[key];
#endif
got.Should().BeSameAs(value);
}

[Fact]
public void Put_should_put_item_using_passed_sliding_ttl_maxvalue()
{
#if PORTABLE
MemoryCacheImplementation memoryCache = new Microsoft.Extensions.Caching.Memory.MemoryCache(new Microsoft.Extensions.Caching.Memory.MemoryCacheOptions());
#else
MemoryCacheImplementation memoryCache = System.Runtime.Caching.MemoryCache.Default;
#endif

string key = "anything";
object value = new object();

MemoryCacheProvider provider = new MemoryCacheProvider(memoryCache);

TimeSpan maxSlidingExpiration =
#if PORTABLE
TimeSpan.MaxValue
#else
TimeSpan.FromDays(365) // This is the maximum permitted sliding ttl for .NetFramework4.0 and 4.5 MemoryCache.
#endif
;

Ttl ttl = new Ttl(maxSlidingExpiration, true);
provider.Put(key, value, ttl);

#if PORTABLE
object got;
memoryCache.TryGetValue(key, out got);
#else
object got = memoryCache[key];
#endif
got.Should().BeSameAs(value);
}

[Fact]
public void Put_should_put_item_using_passed_nonsliding_ttl_zero()
{
#if PORTABLE
MemoryCacheImplementation memoryCache = new Microsoft.Extensions.Caching.Memory.MemoryCache(new Microsoft.Extensions.Caching.Memory.MemoryCacheOptions());
#else
MemoryCacheImplementation memoryCache = System.Runtime.Caching.MemoryCache.Default;
#endif

string key = "anything";
object value = new object();

MemoryCacheProvider provider = new MemoryCacheProvider(memoryCache);

TimeSpan minExpiration =
#if PORTABLE
TimeSpan.FromMilliseconds(1) // This is the minimum permitted non-sliding ttl for .NetStandard
#else
TimeSpan.Zero
#endif
;

Ttl ttl = new Ttl(minExpiration, false);
provider.Put(key, value, ttl);

Thread.Sleep(TimeSpan.FromMilliseconds(10));

#if PORTABLE
object got;
memoryCache.TryGetValue(key, out got);
#else
object got = memoryCache[key];
#endif
got.Should().BeNull();
}

[Fact]
public void Put_should_put_item_using_passed_sliding_ttl_zero()
{
#if PORTABLE
MemoryCacheImplementation memoryCache = new Microsoft.Extensions.Caching.Memory.MemoryCache(new Microsoft.Extensions.Caching.Memory.MemoryCacheOptions());
#else
MemoryCacheImplementation memoryCache = System.Runtime.Caching.MemoryCache.Default;
#endif

string key = "anything";
object value = new object();

MemoryCacheProvider provider = new MemoryCacheProvider(memoryCache);

TimeSpan minExpiration =
#if PORTABLE
TimeSpan.FromMilliseconds(1) // This is the minimum permitted sliding ttl for .NetStandard
#else
TimeSpan.Zero
#endif
;

Ttl ttl = new Ttl(minExpiration, false);
provider.Put(key, value, ttl);

Thread.Sleep(TimeSpan.FromMilliseconds(10));

#if PORTABLE
object got;
memoryCache.TryGetValue(key, out got);
#else
object got = memoryCache[key];
#endif
got.Should().BeNull();
}
#endregion

#endregion
}
}

0 comments on commit 36b4ecf

Please sign in to comment.