Skip to content

Commit

Permalink
Add Compaction logging (#510)
Browse files Browse the repository at this point in the history
* Add logging for compaction test

* Fix AddAndReplaceEntries_AreThreadSafe
  • Loading branch information
JunTaoLuo authored Nov 16, 2018
1 parent 678fc58 commit c3c9c55
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 11 deletions.
26 changes: 25 additions & 1 deletion src/Caching/Memory/src/MemoryCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Internal;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;

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

// We store the delegates locally to prevent allocations
// every time a new CacheEntry is created.
Expand All @@ -35,13 +38,27 @@ public class MemoryCache : IMemoryCache
/// </summary>
/// <param name="optionsAccessor">The options of the cache.</param>
public MemoryCache(IOptions<MemoryCacheOptions> optionsAccessor)
: this(optionsAccessor, NullLoggerFactory.Instance) { }

/// <summary>
/// Creates a new <see cref="MemoryCache"/> instance.
/// </summary>
/// <param name="optionsAccessor">The options of the cache.</param>
/// <param name="loggerFactory"></param>
public MemoryCache(IOptions<MemoryCacheOptions> optionsAccessor, ILoggerFactory loggerFactory)
{
if (optionsAccessor == null)
{
throw new ArgumentNullException(nameof(optionsAccessor));
}

if (loggerFactory == null)
{
throw new ArgumentNullException(nameof(loggerFactory));
}

_options = optionsAccessor.Value;
_logger = loggerFactory.CreateLogger<MemoryCache>();

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

private void TriggerOvercapacityCompaction()
{
_logger.LogDebug("Overcapacity compaction triggered");

// Spawn background thread for compaction
ThreadPool.QueueUserWorkItem(s => OvercapacityCompaction((MemoryCache)s), this);
}

private static void OvercapacityCompaction(MemoryCache cache)
{
var currentSize = Interlocked.Read(ref cache._cacheSize);

cache._logger.LogDebug($"Overcapacity compaction executing. Current size {currentSize}");

var lowWatermark = cache._options.SizeLimit * (1 - cache._options.CompactionPercentage);
if (currentSize > lowWatermark)
{
cache.Compact(currentSize - (long)lowWatermark, entry => entry.Size.Value);
}

cache._logger.LogDebug($"Overcapacity compaction executed. New size {Interlocked.Read(ref cache._cacheSize)}");
}

/// Remove at least the given percentage (0.10 for 10%) of the total entries (or estimated memory?), according to the following policy:
Expand Down Expand Up @@ -481,4 +505,4 @@ private static void ValidateCacheKey(object key)
}
}
}
}
}
14 changes: 12 additions & 2 deletions src/Caching/Memory/src/MemoryDistributedCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;

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

public MemoryDistributedCache(IOptions<MemoryDistributedCacheOptions> optionsAccessor)
: this(optionsAccessor, NullLoggerFactory.Instance) { }

public MemoryDistributedCache(IOptions<MemoryDistributedCacheOptions> optionsAccessor, ILoggerFactory loggerFactory)
{
if (optionsAccessor == null)
{
throw new ArgumentNullException(nameof(optionsAccessor));
}

_memCache = new MemoryCache(optionsAccessor.Value);
if (loggerFactory == null)
{
throw new ArgumentNullException(nameof(loggerFactory));
}

_memCache = new MemoryCache(optionsAccessor.Value, loggerFactory);
}

public byte[] Get(string key)
Expand Down Expand Up @@ -134,4 +144,4 @@ public void Remove(string key)
return CompletedTask;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<ItemGroup>
<Reference Include="Microsoft.Extensions.Caching.Abstractions" />
<Reference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
<Reference Include="Microsoft.Extensions.Logging.Abstractions" />
<Reference Include="Microsoft.Extensions.Options" />
</ItemGroup>

Expand Down
9 changes: 5 additions & 4 deletions src/Caching/Memory/test/CapacityTests.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Memory.Infrastructure;
using Microsoft.Extensions.Internal;
using Microsoft.Extensions.Logging.Testing;
using Xunit;

namespace Microsoft.Extensions.Caching.Memory
{
public class CapacityTests
public class CapacityTests : LoggedTestBase
{
[Fact]
public void MemoryDistributedCacheOptionsDefaultsTo200MBSizeLimit()
Expand Down Expand Up @@ -115,7 +116,7 @@ public async Task DoNotAddIfSizeOverflows()
var cache = new MemoryCache(new MemoryCacheOptions
{
SizeLimit = long.MaxValue
});
}, LoggerFactory);

var entryOptions = new MemoryCacheEntryOptions { Size = long.MaxValue };
var sem = new SemaphoreSlim(0, 1);
Expand Down Expand Up @@ -408,4 +409,4 @@ public void NoCompactionWhenNoMaximumEntriesCountSpecified()
Assert.Equal(6, cache.Count);
}
}
}
}
8 changes: 4 additions & 4 deletions src/Caching/Memory/test/MemoryCacheSetAndRemoveTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -553,7 +553,7 @@ public void AddAndReplaceEntries_AreThreadSafe()
var entrySize = random.Next(0, 5);
cache.Set(random.Next(0, 10), entrySize, new MemoryCacheEntryOptions { Size = entrySize });
}
}, cts.Token);
});

var task1 = Task.Run(() =>
{
Expand All @@ -562,7 +562,7 @@ public void AddAndReplaceEntries_AreThreadSafe()
var entrySize = random.Next(0, 5);
cache.Set(random.Next(0, 10), entrySize, new MemoryCacheEntryOptions { Size = entrySize });
}
}, cts.Token);
});

var task2 = Task.Run(() =>
{
Expand All @@ -571,7 +571,7 @@ public void AddAndReplaceEntries_AreThreadSafe()
var entrySize = random.Next(0, 5);
cache.Set(random.Next(0, 10), entrySize, new MemoryCacheEntryOptions { Size = entrySize });
}
}, cts.Token);
});

cts.CancelAfter(TimeSpan.FromSeconds(5));
var task3 = Task.Delay(TimeSpan.FromSeconds(7));
Expand Down Expand Up @@ -643,4 +643,4 @@ private class TestKey
public override int GetHashCode() => 0;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">

<Import Project="$(MSBuildThisFileDirectory)..\..\..\Logging\Logging.Testing\src\build\Microsoft.Extensions.Logging.Testing.props" />

<PropertyGroup>
<TargetFrameworks>$(StandardTestTfms)</TargetFrameworks>
</PropertyGroup>

<ItemGroup>
<Reference Include="Microsoft.Extensions.Caching.Memory" />
<Reference Include="Microsoft.Extensions.DependencyInjection" />
<Reference Include="Microsoft.Extensions.Logging.Testing" />
</ItemGroup>

</Project>

0 comments on commit c3c9c55

Please sign in to comment.