Skip to content

Commit 1af60f3

Browse files
committed
Handle TimeSpan.MaxValue expiration
and matching boundary tests
1 parent fee0644 commit 1af60f3

File tree

2 files changed

+140
-4
lines changed

2 files changed

+140
-4
lines changed

src/Polly.Caching.MemoryCache.Shared/MemoryCacheProvider.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,27 +62,29 @@ public object Get(String key)
6262
/// <param name="ttl">The time-to-live for the cache entry.</param>
6363
public void Put(string key, object value, Ttl ttl)
6464
{
65+
TimeSpan remaining = DateTimeOffset.MaxValue - SystemClock.DateTimeOffsetUtcNow();
66+
6567
#if PORTABLE
6668
using (Microsoft.Extensions.Caching.Memory.ICacheEntry entry = _cache.CreateEntry(key)) {
6769
entry.Value = value;
6870
if (ttl.SlidingExpiration)
6971
{
70-
entry.SlidingExpiration = ttl.Timespan;
72+
entry.SlidingExpiration = ttl.Timespan < remaining ? ttl.Timespan : remaining;
7173
}
7274
else
7375
{
74-
entry.AbsoluteExpirationRelativeToNow = ttl.Timespan;
76+
entry.AbsoluteExpirationRelativeToNow = ttl.Timespan < remaining ? ttl.Timespan : remaining;
7577
}
7678
}
7779
#else
7880
System.Runtime.Caching.CacheItemPolicy cacheItemPolicy = new System.Runtime.Caching.CacheItemPolicy();
7981
if (ttl.SlidingExpiration)
8082
{
81-
cacheItemPolicy.SlidingExpiration = ttl.Timespan;
83+
cacheItemPolicy.SlidingExpiration = ttl.Timespan < remaining ? ttl.Timespan : remaining;
8284
}
8385
else
8486
{
85-
cacheItemPolicy.AbsoluteExpiration = SystemClock.DateTimeOffsetUtcNow().Add(ttl.Timespan);
87+
cacheItemPolicy.AbsoluteExpiration = ttl.Timespan < remaining ? SystemClock.DateTimeOffsetUtcNow().Add(ttl.Timespan) : DateTimeOffset.MaxValue;
8688
}
8789
_cache.Set(key, value, cacheItemPolicy);
8890
#endif

src/Polly.Caching.MemoryCache.SharedSpecs/MemoryCacheProviderSpecs.cs

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,140 @@ public void Put_should_put_item_using_passed_sliding_ttl()
189189
}
190190
}
191191

192+
#region Boundary tests
193+
194+
[Fact]
195+
public void Put_should_put_item_using_passed_nonsliding_ttl_maxvalue()
196+
{
197+
#if PORTABLE
198+
MemoryCacheImplementation memoryCache = new Microsoft.Extensions.Caching.Memory.MemoryCache(new Microsoft.Extensions.Caching.Memory.MemoryCacheOptions());
199+
#else
200+
MemoryCacheImplementation memoryCache = System.Runtime.Caching.MemoryCache.Default;
201+
#endif
202+
203+
string key = "anything";
204+
object value = new object();
205+
206+
MemoryCacheProvider provider = new MemoryCacheProvider(memoryCache);
207+
Ttl ttl = new Ttl(TimeSpan.MaxValue, false);
208+
provider.Put(key, value, ttl);
209+
210+
#if PORTABLE
211+
object got;
212+
memoryCache.TryGetValue(key, out got);
213+
#else
214+
object got = memoryCache[key];
215+
#endif
216+
got.Should().BeSameAs(value);
217+
}
218+
219+
[Fact]
220+
public void Put_should_put_item_using_passed_sliding_ttl_maxvalue()
221+
{
222+
#if PORTABLE
223+
MemoryCacheImplementation memoryCache = new Microsoft.Extensions.Caching.Memory.MemoryCache(new Microsoft.Extensions.Caching.Memory.MemoryCacheOptions());
224+
#else
225+
MemoryCacheImplementation memoryCache = System.Runtime.Caching.MemoryCache.Default;
226+
#endif
227+
228+
string key = "anything";
229+
object value = new object();
230+
231+
MemoryCacheProvider provider = new MemoryCacheProvider(memoryCache);
232+
233+
TimeSpan maxSlidingExpiration =
234+
#if PORTABLE
235+
TimeSpan.MaxValue
236+
#else
237+
TimeSpan.FromDays(365) // This is the maximum permitted sliding ttl for .NetFramework4.0 and 4.5 MemoryCache.
238+
#endif
239+
;
240+
241+
Ttl ttl = new Ttl(maxSlidingExpiration, true);
242+
provider.Put(key, value, ttl);
243+
244+
#if PORTABLE
245+
object got;
246+
memoryCache.TryGetValue(key, out got);
247+
#else
248+
object got = memoryCache[key];
249+
#endif
250+
got.Should().BeSameAs(value);
251+
}
252+
253+
[Fact]
254+
public void Put_should_put_item_using_passed_nonsliding_ttl_zero()
255+
{
256+
#if PORTABLE
257+
MemoryCacheImplementation memoryCache = new Microsoft.Extensions.Caching.Memory.MemoryCache(new Microsoft.Extensions.Caching.Memory.MemoryCacheOptions());
258+
#else
259+
MemoryCacheImplementation memoryCache = System.Runtime.Caching.MemoryCache.Default;
260+
#endif
261+
262+
string key = "anything";
263+
object value = new object();
264+
265+
MemoryCacheProvider provider = new MemoryCacheProvider(memoryCache);
266+
267+
TimeSpan minExpiration =
268+
#if PORTABLE
269+
TimeSpan.FromMilliseconds(1) // This is the minimum permitted non-sliding ttl for .NetStandard
270+
#else
271+
TimeSpan.Zero
272+
#endif
273+
;
274+
275+
Ttl ttl = new Ttl(minExpiration, false);
276+
provider.Put(key, value, ttl);
277+
278+
Thread.Sleep(TimeSpan.FromMilliseconds(10));
279+
280+
#if PORTABLE
281+
object got;
282+
memoryCache.TryGetValue(key, out got);
283+
#else
284+
object got = memoryCache[key];
285+
#endif
286+
got.Should().BeNull();
287+
}
288+
289+
[Fact]
290+
public void Put_should_put_item_using_passed_sliding_ttl_zero()
291+
{
292+
#if PORTABLE
293+
MemoryCacheImplementation memoryCache = new Microsoft.Extensions.Caching.Memory.MemoryCache(new Microsoft.Extensions.Caching.Memory.MemoryCacheOptions());
294+
#else
295+
MemoryCacheImplementation memoryCache = System.Runtime.Caching.MemoryCache.Default;
296+
#endif
297+
298+
string key = "anything";
299+
object value = new object();
300+
301+
MemoryCacheProvider provider = new MemoryCacheProvider(memoryCache);
302+
303+
TimeSpan minExpiration =
304+
#if PORTABLE
305+
TimeSpan.FromMilliseconds(1) // This is the minimum permitted sliding ttl for .NetStandard
306+
#else
307+
TimeSpan.Zero
308+
#endif
309+
;
310+
311+
Ttl ttl = new Ttl(minExpiration, false);
312+
provider.Put(key, value, ttl);
313+
314+
Thread.Sleep(TimeSpan.FromMilliseconds(10));
315+
316+
#if PORTABLE
317+
object got;
318+
memoryCache.TryGetValue(key, out got);
319+
#else
320+
object got = memoryCache[key];
321+
#endif
322+
got.Should().BeNull();
323+
}
324+
#endregion
325+
192326
#endregion
193327
}
194328
}

0 commit comments

Comments
 (0)