Skip to content

Commit

Permalink
dispose of previous inner (in-memory) cache when calling ClearAll()
Browse files Browse the repository at this point in the history
  • Loading branch information
Yagel committed Jul 25, 2021
1 parent ee400cc commit 61f78ff
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 5 deletions.
37 changes: 37 additions & 0 deletions Core.UnitTests/CacheInterfaceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace PubComp.Caching.Core.UnitTests
Expand Down Expand Up @@ -214,6 +215,42 @@ public void TestCacheTimeToLive_Constant()
Assert.AreNotEqual("1", result);
}

[TestMethod]
[Ignore("Diagnose manually the memory consumption")]
public void LotsOfClearAll()
{
var cache = GetCache("cache1");
for (var i = 0; i < 5000; i++)
{
cache.ClearAll();
}
Thread.Sleep(1000);
GC.Collect();
Thread.Sleep(1000);
for (var i = 0; i < 5000; i++)
{
cache.ClearAll();
}
}

[TestMethod]
[Ignore("Diagnose manually the memory consumption")]
public async Task LotsOfClearAsyncAll()
{
var cache = GetCache("cache1");
for (var i = 0; i < 5000; i++)
{
await cache.ClearAllAsync().ConfigureAwait(false);
}
await Task.Delay(1000);
GC.Collect();
await Task.Delay(1000);
for (var i = 0; i < 5000; i++)
{
await cache.ClearAllAsync().ConfigureAwait(false);
}
}

[TestMethod]
public void TestCacheTryGet()
{
Expand Down
1 change: 1 addition & 0 deletions SystemRuntime.UnitTests/InMemoryCacheTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ int Get()
}

[TestMethod]
[Ignore("only a one time test needed")]
public void LoadTest_LockingStrategiesComparison()
{
const int numberOfThreads = 16;
Expand Down
17 changes: 14 additions & 3 deletions SystemRuntime/ObjectCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -220,13 +220,24 @@ public Task ClearAsync(string key)

public void ClearAll()
{
innerCache = new System.Runtime.Caching.MemoryCache(this.name);
var previousInnerCache = System.Threading.Interlocked.Exchange(ref innerCache,
new System.Runtime.Caching.MemoryCache(this.name));

if (previousInnerCache is IDisposable disposeMe)
{
// I had a concern that some classes will hold the reference of the previous cache
// and that the disposing will cause in certain edge race cases a serious exception (AlreadyDisposedException).
// But using the dispose cache object is ok, but does nothing and no exception as well.
// Set: will not set, as if the ClearAll was called a nanosecond after setting
// Get: will get nothing, as if the ClearAll was called a nanosecond before getting
disposeMe.Dispose();
}
}

public Task ClearAllAsync()
{
innerCache = new System.Runtime.Caching.MemoryCache(this.name);
return Task.FromResult<object>(null);
ClearAll();
return Task.CompletedTask;
}

public object GetDetails() => new
Expand Down
4 changes: 2 additions & 2 deletions SystemRuntime/SystemRuntime.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
<AssemblyName>PubComp.Caching.SystemRuntime</AssemblyName>
<RootNamespace>PubComp.Caching.SystemRuntime</RootNamespace>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Version>5.0.0</Version>
<Version>5.0.1</Version>
<AssemblyVersion>5.0.0.0</AssemblyVersion>
<FileVersion>5.0.0.0</FileVersion>
<FileVersion>5.0.1.0</FileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<NoWarn>1701;1702;1591</NoWarn>
Expand Down

0 comments on commit 61f78ff

Please sign in to comment.