LazyCache
LazyCache copied to clipboard
Using ExpirationMode.ImmediateEviction ignores sliding expiration value
Describe the bug Hi, I am trying to use ExpirationMode.ImmediateEviction with sliding expiration in my project and this makes the entry to update every time I access it, ignoring the sliding expiration value
To Reproduce
for (var i = 1; i <= 5; i++)
{
await _cache.GetOrAddAsync("1", entry => Task.FromResult(new Random().Next(1, 10)),
new LazyCacheEntryOptions {ExpirationMode = ExpirationMode.ImmediateEviction}
.SetSlidingExpiration(TimeSpan.FromSeconds(5))
.RegisterPostEvictionCallback((key, value, reason, state) =>
{
Debug.WriteLine($"{key} {((Task<int>) value).Result}");
}));
}
Expected behavior The sliding expiration time shouldn't be ignored
** Framework and Platform
- OS: Windows 10 21H1
- Framework: netcoreapp3.1
- LazyCache Version: 2.1.3
I suspect the bug is because the immediate expiration stuff was never tested with sliding expiration. Looking at https://github.com/alastairtree/LazyCache/blob/master/LazyCache/Providers/MemoryCacheProvider.cs#L55 you can see it seems to cancel based on absolute expiration so some additional code would be needed detect sliding to make it work.
expiryTokenSource.CancelAfter(lazyPolicy.ImmediateAbsoluteExpirationRelativeToNow);
and note the related code in https://github.com/alastairtree/LazyCache/blob/master/LazyCache/MemoryCacheEntryOptionsExtensions.cs
Just released a new version, may well fix this. Let us know how you get on?
Install-Package LazyCache -Version 2.4.0
Just released a new version, may well fix this. Let us know how you get on?
Install-Package LazyCache -Version 2.4.0
Unfortunately this doesn't fix it
A workaround is to use MemoryCacheEntryOptions instead of LazyCacheEntryOptions
Hi @ExLuzZziVo, i am also seeing this issue please could you detail the workaround ?
A PR with a failing unit test would help track this down if you are willing?
Hi @ExLuzZziVo, i am also seeing this issue please could you detail the workaround ?
Just replace new LazyCacheEntryOptions {ExpirationMode = ExpirationMode.ImmediateEviction} with new MemoryCacheEntryOptions() in above example and it will work as expected
A PR with a failing unit test would help track this down if you are willing?
I will try to make a PR next week
@alastairtree There is a strange thing with the unit test for this issue. If I run the test method separately, it fails. If I run all the tests, it passes. I have tried to set the cache key manually but the result was the same. My test method:
[Test]
public void GetFromCacheTwiceAtSameTimeOnlyAddsOnceWithSliding()
{
var times = 0;
var lazyCacheEntryOptions = new LazyCacheEntryOptions { ExpirationMode = ExpirationMode.ImmediateEviction }
.SetSlidingExpiration(TimeSpan.FromSeconds(20));
var t1 = Task.Factory.StartNew(() =>
{
sut.GetOrAdd(TestKey, () =>
{
Interlocked.Increment(ref times);
return new DateTime(2001, 01, 01);
}, lazyCacheEntryOptions);
});
var t2 = Task.Factory.StartNew(() =>
{
sut.GetOrAdd(TestKey, () =>
{
Interlocked.Increment(ref times);
return new DateTime(2001, 01, 01);
}, lazyCacheEntryOptions);
});
Task.WaitAll(t1, t2);
Assert.AreEqual(1, times);
}