Skip to content

Commit

Permalink
Fixed issue #121. (#122)
Browse files Browse the repository at this point in the history
  • Loading branch information
chullybun authored Apr 7, 2021
1 parent 679799f commit aa9b984
Show file tree
Hide file tree
Showing 6 changed files with 151 additions and 6 deletions.
2 changes: 1 addition & 1 deletion src/Beef.Core/Beef.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<RootNamespace>Beef</RootNamespace>
<Version>4.1.8</Version>
<Version>4.1.9</Version>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Authors>Beef Developers</Authors>
<Company>Avanade</Company>
Expand Down
3 changes: 3 additions & 0 deletions src/Beef.Core/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

Represents the **NuGet** versions.

## v4.1.9
- *Fixed:* Issue [121](https://github.com/Avanade/Beef/issues/121). `SlidingCachePolicy` will now cache correctly after first expiry.

## v4.1.8
- *Enhancement:* Added new `InvokerBase<TParam, TResult>` to enable the ability to specifically define the return `Type`.

Expand Down
5 changes: 4 additions & 1 deletion src/Beef.Core/Caching/Policy/SlidingCachePolicy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace Beef.Caching.Policy
/// </summary>
public sealed class SlidingCachePolicy : ICachePolicy
{
private TimeSpan _duration = new TimeSpan(1, 0, 0);
private TimeSpan _duration = new(1, 0, 0);
private TimeSpan? _randomizerOffset;
private TimeSpan _maxDuration;
private DateTime? _maxExpiry;
Expand Down Expand Up @@ -116,6 +116,9 @@ public void Refresh()
public void Reset()
{
DateTime now = Entities.Cleaner.Clean(DateTime.Now);
if (_maxExpiry.HasValue && _maxExpiry <= now)
_maxExpiry = null;

DateTime? expiry = now.Add(_duration);

if (!_maxExpiry.HasValue && _maxDuration.TotalMilliseconds > 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,10 @@ private TColl GetByTenantId(Guid tenantId)

var coll = GetCollectionInternal();

var policy = (ICachePolicy)GetPolicy().Clone();
var policy = cv.Policy ?? (ICachePolicy)GetPolicy().Clone();
policy.Reset();

cv = _dict.GetOrAdd(tenantId, new CacheValue<TColl> { Policy = policy, Value = coll });
cv = _dict.GetOrAdd(tenantId, t => new CacheValue<TColl> { Policy = policy, Value = coll });
return cv.Value;
}
}
Expand Down
74 changes: 72 additions & 2 deletions tests/Beef.Core.UnitTest/RefData/Caching/ReferenceDataCacheTest.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Copyright (c) Avanade. Licensed under the MIT License. See https://github.com/Avanade/Beef

using Beef.Caching.Policy;
using Beef.RefData;
using Beef.RefData.Caching;
using NUnit.Framework;
Expand All @@ -26,7 +27,6 @@ private class TestRdCollection : ReferenceDataCollectionBase<TestRd>
public void Exercise()
{
UnitTest.Caching.Policy.CachePolicyManagerTest.TestSetUp();

var coll = new TestRdCollection
{
new TestRd { Id = 1, Code = "A" },
Expand Down Expand Up @@ -71,5 +71,75 @@ public void Exercise()
Assert.AreEqual(2, rdc.Count);
Assert.IsFalse(rdc.IsExpired);
}

[Test]
public void Exercise_SlidingCache()
{
UnitTest.Caching.Policy.CachePolicyManagerTest.TestSetUp();

var coll = new TestRdCollection
{
new TestRd { Id = 1, Code = "A" },
new TestRd { Id = 2, Code = "B" }
};

var policy = new SlidingCachePolicy
{
Duration = new TimeSpan(0, 0, 3),
MaxDuration = new TimeSpan(0, 0, 4)
};

int dataRequests = 0;
var rdc = new ReferenceDataCache<TestRdCollection, TestRd>(() => { dataRequests++; return Task.FromResult(coll); });

CachePolicyManager.Current.Set(rdc.PolicyKey, policy);

// Nothing loaded.
Assert.AreEqual(0, dataRequests);
Assert.AreEqual(0, rdc.Count);
Assert.IsTrue(rdc.IsExpired);

// Now loaded.
var c = rdc.GetCollection();
Assert.AreEqual(1, dataRequests);
Assert.IsNotNull(c);
Assert.AreEqual(2, c.ActiveList.Count);
Assert.AreEqual(2, rdc.Count);
Assert.IsFalse(rdc.IsExpired);

// Multiple cycles to test Max cache
for (int cycle = 0; cycle < 3; cycle++)
{
coll.Add(new TestRd { Id = 3 + cycle, Code = $"X{3 + cycle}" });

// Running till max cache expires.
while (!rdc.IsExpired)
{
c = rdc.GetCollection();
Assert.AreEqual(1 + cycle, dataRequests);
Assert.IsNotNull(c);
Assert.AreEqual(3 + cycle, c.ActiveList.Count);
Assert.AreEqual(3 + cycle, rdc.Count);
Assert.IsFalse(rdc.IsExpired);
System.Threading.Thread.Sleep((int)Math.Floor(policy.Duration.TotalSeconds / 2));
}

// reload collection cached.
c = rdc.GetCollection();
Assert.AreEqual(2 + cycle, dataRequests);
Assert.IsNotNull(c);
Assert.AreEqual(3 + cycle, c.ActiveList.Count);
Assert.AreEqual(3 + cycle, rdc.Count);
Assert.IsFalse(rdc.IsExpired);

// New collection cached.
c = rdc.GetCollection();
Assert.AreEqual(2 + cycle, dataRequests);
Assert.IsNotNull(c);
Assert.AreEqual(3 + cycle, c.ActiveList.Count);
Assert.AreEqual(3 + cycle, rdc.Count);
Assert.IsFalse(rdc.IsExpired);
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -183,5 +183,74 @@ private void Timer(int number, Guid key, Action a)
sw.Stop();
TestContext.WriteLine($"{System.Threading.Thread.CurrentThread.ManagedThreadId}: {number}, {key}, {sw.ElapsedMilliseconds}");
}

[Test]
public void Exercise_SlidingCache()
{
UnitTest.Caching.Policy.CachePolicyManagerTest.TestSetUp();

var coll = new TestRdCollection
{
new TestRd { Id = 1, Code = "A" },
new TestRd { Id = 2, Code = "B" }
};

var policy = new SlidingCachePolicy
{
Duration = new TimeSpan(0, 0, 3),
MaxDuration = new TimeSpan(0, 0, 4)
};

int dataRequests = 0;
var rdc = new ReferenceDataMultiTenantCache<TestRdCollection, TestRd>(() => { dataRequests++; return GetData(); });

CachePolicyManager.Current.Set(rdc.PolicyKey, policy);
ExecutionContext.Current.TenantId = GetGuid(08);

// Nothing loaded.
Assert.AreEqual(0, dataRequests);
Assert.AreEqual(0, rdc.Count);
Assert.IsTrue(rdc.IsExpired);

// Now loaded.
var c = rdc.GetCollection();
Assert.AreEqual(1, dataRequests);
Assert.IsNotNull(c);
Assert.AreEqual(2, c.ActiveList.Count);
Assert.AreEqual(1, rdc.Count);
Assert.IsFalse(rdc.IsExpired);

// Multiple cycles to test Max cache
for (int cycle = 0; cycle < 3; cycle++)
{
// Running till max cache expires.
while (!rdc.IsExpired)
{
c = rdc.GetCollection();
Assert.AreEqual(1 + cycle, dataRequests);
Assert.IsNotNull(c);
Assert.AreEqual(2, c.ActiveList.Count);
Assert.AreEqual(1, rdc.Count);
Assert.IsFalse(rdc.IsExpired);
System.Threading.Thread.Sleep((int)Math.Floor(policy.Duration.TotalSeconds / 2));
}

// reload collection cached.
c = rdc.GetCollection();
Assert.AreEqual(2 + cycle, dataRequests);
Assert.IsNotNull(c);
Assert.AreEqual(2, c.ActiveList.Count);
Assert.AreEqual(1, rdc.Count);
Assert.IsFalse(rdc.IsExpired);

// New collection cached.
c = rdc.GetCollection();
Assert.AreEqual(2 + cycle, dataRequests);
Assert.IsNotNull(c);
Assert.AreEqual(2, c.ActiveList.Count);
Assert.AreEqual(1, rdc.Count);
Assert.IsFalse(rdc.IsExpired);
}
}
}
}

0 comments on commit aa9b984

Please sign in to comment.