Skip to content

Commit 3205599

Browse files
authored
Add Compaction logging (dotnet/extensions#510)
* Add logging for compaction test * Fix AddAndReplaceEntries_AreThreadSafe \n\nCommit migrated from dotnet/extensions@c3c9c55
1 parent bd2bb77 commit 3205599

6 files changed

Lines changed: 50 additions & 11 deletions

src/Caching/Memory/src/MemoryCache.cs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
using System.Threading;
99
using System.Threading.Tasks;
1010
using Microsoft.Extensions.Internal;
11+
using Microsoft.Extensions.Logging;
12+
using Microsoft.Extensions.Logging.Abstractions;
1113
using Microsoft.Extensions.Options;
1214

1315
namespace Microsoft.Extensions.Caching.Memory
@@ -21,6 +23,7 @@ public class MemoryCache : IMemoryCache
2123
private readonly ConcurrentDictionary<object, CacheEntry> _entries;
2224
private long _cacheSize = 0;
2325
private bool _disposed;
26+
private ILogger _logger;
2427

2528
// We store the delegates locally to prevent allocations
2629
// every time a new CacheEntry is created.
@@ -35,13 +38,27 @@ public class MemoryCache : IMemoryCache
3538
/// </summary>
3639
/// <param name="optionsAccessor">The options of the cache.</param>
3740
public MemoryCache(IOptions<MemoryCacheOptions> optionsAccessor)
41+
: this(optionsAccessor, NullLoggerFactory.Instance) { }
42+
43+
/// <summary>
44+
/// Creates a new <see cref="MemoryCache"/> instance.
45+
/// </summary>
46+
/// <param name="optionsAccessor">The options of the cache.</param>
47+
/// <param name="loggerFactory"></param>
48+
public MemoryCache(IOptions<MemoryCacheOptions> optionsAccessor, ILoggerFactory loggerFactory)
3849
{
3950
if (optionsAccessor == null)
4051
{
4152
throw new ArgumentNullException(nameof(optionsAccessor));
4253
}
4354

55+
if (loggerFactory == null)
56+
{
57+
throw new ArgumentNullException(nameof(loggerFactory));
58+
}
59+
4460
_options = optionsAccessor.Value;
61+
_logger = loggerFactory.CreateLogger<MemoryCache>();
4562

4663
_entries = new ConcurrentDictionary<object, CacheEntry>();
4764
_setEntry = SetEntry;
@@ -341,18 +358,25 @@ private bool UpdateCacheSizeExceedsCapacity(CacheEntry entry)
341358

342359
private void TriggerOvercapacityCompaction()
343360
{
361+
_logger.LogDebug("Overcapacity compaction triggered");
362+
344363
// Spawn background thread for compaction
345364
ThreadPool.QueueUserWorkItem(s => OvercapacityCompaction((MemoryCache)s), this);
346365
}
347366

348367
private static void OvercapacityCompaction(MemoryCache cache)
349368
{
350369
var currentSize = Interlocked.Read(ref cache._cacheSize);
370+
371+
cache._logger.LogDebug($"Overcapacity compaction executing. Current size {currentSize}");
372+
351373
var lowWatermark = cache._options.SizeLimit * (1 - cache._options.CompactionPercentage);
352374
if (currentSize > lowWatermark)
353375
{
354376
cache.Compact(currentSize - (long)lowWatermark, entry => entry.Size.Value);
355377
}
378+
379+
cache._logger.LogDebug($"Overcapacity compaction executed. New size {Interlocked.Read(ref cache._cacheSize)}");
356380
}
357381

358382
/// Remove at least the given percentage (0.10 for 10%) of the total entries (or estimated memory?), according to the following policy:
@@ -481,4 +505,4 @@ private static void ValidateCacheKey(object key)
481505
}
482506
}
483507
}
484-
}
508+
}

src/Caching/Memory/src/MemoryDistributedCache.cs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
using System.Threading;
66
using System.Threading.Tasks;
77
using Microsoft.Extensions.Caching.Memory;
8+
using Microsoft.Extensions.Logging;
9+
using Microsoft.Extensions.Logging.Abstractions;
810
using Microsoft.Extensions.Options;
911

1012
namespace Microsoft.Extensions.Caching.Distributed
@@ -16,13 +18,21 @@ public class MemoryDistributedCache : IDistributedCache
1618
private readonly IMemoryCache _memCache;
1719

1820
public MemoryDistributedCache(IOptions<MemoryDistributedCacheOptions> optionsAccessor)
21+
: this(optionsAccessor, NullLoggerFactory.Instance) { }
22+
23+
public MemoryDistributedCache(IOptions<MemoryDistributedCacheOptions> optionsAccessor, ILoggerFactory loggerFactory)
1924
{
2025
if (optionsAccessor == null)
2126
{
2227
throw new ArgumentNullException(nameof(optionsAccessor));
2328
}
2429

25-
_memCache = new MemoryCache(optionsAccessor.Value);
30+
if (loggerFactory == null)
31+
{
32+
throw new ArgumentNullException(nameof(loggerFactory));
33+
}
34+
35+
_memCache = new MemoryCache(optionsAccessor.Value, loggerFactory);
2636
}
2737

2838
public byte[] Get(string key)
@@ -134,4 +144,4 @@ public void Remove(string key)
134144
return CompletedTask;
135145
}
136146
}
137-
}
147+
}

src/Caching/Memory/src/Microsoft.Extensions.Caching.Memory.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
<ItemGroup>
1212
<Reference Include="Microsoft.Extensions.Caching.Abstractions" />
1313
<Reference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
14+
<Reference Include="Microsoft.Extensions.Logging.Abstractions" />
1415
<Reference Include="Microsoft.Extensions.Options" />
1516
</ItemGroup>
1617

src/Caching/Memory/test/CapacityTests.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
1-
// Copyright (c) .NET Foundation. All rights reserved.
1+
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

44
using System;
55
using System.Threading;
66
using System.Threading.Tasks;
77
using Microsoft.Extensions.Caching.Memory.Infrastructure;
88
using Microsoft.Extensions.Internal;
9+
using Microsoft.Extensions.Logging.Testing;
910
using Xunit;
1011

1112
namespace Microsoft.Extensions.Caching.Memory
1213
{
13-
public class CapacityTests
14+
public class CapacityTests : LoggedTestBase
1415
{
1516
[Fact]
1617
public void MemoryDistributedCacheOptionsDefaultsTo200MBSizeLimit()
@@ -115,7 +116,7 @@ public async Task DoNotAddIfSizeOverflows()
115116
var cache = new MemoryCache(new MemoryCacheOptions
116117
{
117118
SizeLimit = long.MaxValue
118-
});
119+
}, LoggerFactory);
119120

120121
var entryOptions = new MemoryCacheEntryOptions { Size = long.MaxValue };
121122
var sem = new SemaphoreSlim(0, 1);
@@ -408,4 +409,4 @@ public void NoCompactionWhenNoMaximumEntriesCountSpecified()
408409
Assert.Equal(6, cache.Count);
409410
}
410411
}
411-
}
412+
}

src/Caching/Memory/test/MemoryCacheSetAndRemoveTests.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -553,7 +553,7 @@ public void AddAndReplaceEntries_AreThreadSafe()
553553
var entrySize = random.Next(0, 5);
554554
cache.Set(random.Next(0, 10), entrySize, new MemoryCacheEntryOptions { Size = entrySize });
555555
}
556-
}, cts.Token);
556+
});
557557

558558
var task1 = Task.Run(() =>
559559
{
@@ -562,7 +562,7 @@ public void AddAndReplaceEntries_AreThreadSafe()
562562
var entrySize = random.Next(0, 5);
563563
cache.Set(random.Next(0, 10), entrySize, new MemoryCacheEntryOptions { Size = entrySize });
564564
}
565-
}, cts.Token);
565+
});
566566

567567
var task2 = Task.Run(() =>
568568
{
@@ -571,7 +571,7 @@ public void AddAndReplaceEntries_AreThreadSafe()
571571
var entrySize = random.Next(0, 5);
572572
cache.Set(random.Next(0, 10), entrySize, new MemoryCacheEntryOptions { Size = entrySize });
573573
}
574-
}, cts.Token);
574+
});
575575

576576
cts.CancelAfter(TimeSpan.FromSeconds(5));
577577
var task3 = Task.Delay(TimeSpan.FromSeconds(7));
@@ -643,4 +643,4 @@ private class TestKey
643643
public override int GetHashCode() => 0;
644644
}
645645
}
646-
}
646+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

3+
<Import Project="$(MSBuildThisFileDirectory)..\..\..\Logging\Logging.Testing\src\build\Microsoft.Extensions.Logging.Testing.props" />
4+
35
<PropertyGroup>
46
<TargetFrameworks>$(StandardTestTfms)</TargetFrameworks>
57
</PropertyGroup>
68

79
<ItemGroup>
810
<Reference Include="Microsoft.Extensions.Caching.Memory" />
911
<Reference Include="Microsoft.Extensions.DependencyInjection" />
12+
<Reference Include="Microsoft.Extensions.Logging.Testing" />
1013
</ItemGroup>
1114

1215
</Project>

0 commit comments

Comments
 (0)