Skip to content

Commit 636d67a

Browse files
Refine .Net Core Memory cache
Fix errors in xml comments, refactor the configuration logic and test it more thoroughly.
1 parent c001ee6 commit 636d67a

File tree

4 files changed

+67
-69
lines changed

4 files changed

+67
-69
lines changed

CoreMemoryCache/NHibernate.Caches.CoreMemoryCache.Tests/CoreMemoryCacheSectionHandlerFixture.cs

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,25 +41,35 @@ public void TestGetConfigNullSection()
4141
var handler = new CoreMemoryCacheSectionHandler();
4242
var section = new XmlDocument();
4343
var result = handler.Create(null, null, section);
44-
Assert.That(result, Is.Not.Null);
45-
Assert.IsTrue(result is CacheConfig[]);
46-
var caches = result as CacheConfig[];
47-
Assert.That(caches.Length, Is.EqualTo(0));
44+
Assert.That(result, Is.Not.Null, "result");
45+
Assert.That(result, Is.InstanceOf<CacheConfig>());
46+
var config = (CacheConfig) result;
47+
Assert.That(config.ExpirationScanFrequency, Is.Null, "ExpirationScanFrequency");
48+
Assert.That(config.Regions, Is.Not.Null, "Regions");
49+
Assert.That(config.Regions.Length, Is.EqualTo(0));
4850
}
4951

5052
[Test]
5153
public void TestGetConfigFromFile()
5254
{
53-
const string xmlSimple = "<corememorycache><cache region=\"foo\" expiration=\"500\" sliding=\"true\" /></corememorycache>";
55+
const string xmlSimple =
56+
"<corememorycache expiration-scan-frequency=\"5\"><cache region=\"foo\" expiration=\"500\" sliding=\"true\" /></corememorycache>";
5457

5558
var handler = new CoreMemoryCacheSectionHandler();
5659
var section = GetConfigurationSection(xmlSimple);
5760
var result = handler.Create(null, null, section);
5861
Assert.That(result, Is.Not.Null);
59-
Assert.IsTrue(result is CacheConfig[]);
60-
var caches = result as CacheConfig[];
61-
Assert.That(caches.Length, Is.EqualTo(1));
62-
Assert.That(caches[0].Properties, Does.ContainKey("cache.use_sliding_expiration"));
62+
Assert.That(result, Is.InstanceOf<CacheConfig>());
63+
var config = (CacheConfig) result;
64+
Assert.That(config.ExpirationScanFrequency, Is.EqualTo("5"), "ExpirationScanFrequency");
65+
66+
Assert.That(config.Regions, Is.Not.Null, "Regions");
67+
Assert.That(config.Regions.Length, Is.EqualTo(1), "Regions count");
68+
Assert.That(config.Regions[0].Region, Is.EqualTo("foo"));
69+
Assert.That(config.Regions[0].Properties, Does.ContainKey("cache.use_sliding_expiration"));
70+
Assert.That(config.Regions[0].Properties["cache.use_sliding_expiration"], Is.EqualTo("true"));
71+
Assert.That(config.Regions[0].Properties, Does.ContainKey("expiration"));
72+
Assert.That(config.Regions[0].Properties["expiration"], Is.EqualTo("500"));
6373
}
6474
}
6575
}

CoreMemoryCache/NHibernate.Caches.CoreMemoryCache/CacheConfig.cs

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,40 @@
33
namespace NHibernate.Caches.CoreMemoryCache
44
{
55
/// <summary>
6-
/// Cache config properties.
6+
/// Cache configuration properties.
77
/// </summary>
88
public class CacheConfig
99
{
1010
/// <summary>
11-
/// Build a cache global configuration.
11+
/// Build a cache configuration.
1212
/// </summary>
1313
/// <param name="expirationScanFrequency">The frequency at which scans for cleaning expired cached item have to be done.</param>
14-
public CacheConfig(string expirationScanFrequency)
14+
/// <param name="regions">The configured cache regions.</param>
15+
public CacheConfig(string expirationScanFrequency, RegionConfig[] regions)
1516
{
1617
ExpirationScanFrequency = expirationScanFrequency;
17-
Global = true;
18+
Regions = regions;
1819
}
1920

21+
/// <summary>The frequency at which scans for cleaning expired cached item have to be done.</summary>
22+
public string ExpirationScanFrequency { get; }
23+
24+
/// <summary>The configured cache regions.</summary>
25+
public RegionConfig[] Regions { get; }
26+
}
27+
28+
/// <summary>
29+
/// Cache region configuration properties.
30+
/// </summary>
31+
public class RegionConfig
32+
{
2033
/// <summary>
2134
/// Build a cache region configuration.
2235
/// </summary>
2336
/// <param name="region">The configured cache region.</param>
2437
/// <param name="expiration">The expiration for the region.</param>
2538
/// <param name="sliding">Whether the expiration should be sliding or not.</param>
26-
public CacheConfig(string region, string expiration, string sliding)
39+
public RegionConfig(string region, string expiration, string sliding)
2740
{
2841
Region = region;
2942
Properties = new Dictionary<string, string>();
@@ -33,15 +46,9 @@ public CacheConfig(string region, string expiration, string sliding)
3346
Properties["cache.use_sliding_expiration"] = sliding;
3447
}
3548

36-
/// <summary>Whether this configuration is global or is a cache region configuration.</summary>
37-
public bool Global { get; }
38-
3949
/// <summary>The region name.</summary>
4050
public string Region { get; }
4151

42-
/// <summary>The frequency at which scans for cleaning expired cached item have to be done.</summary>
43-
public string ExpirationScanFrequency { get; }
44-
4552
/// <summary>The configuration properties.</summary>
4653
public IDictionary<string,string> Properties { get; }
4754
}

CoreMemoryCache/NHibernate.Caches.CoreMemoryCache/CoreMemoryCacheProvider.cs

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public class CoreMemoryCacheProvider : ICacheProvider
3636
{
3737
private static readonly Dictionary<string, IDictionary<string, string>> ConfiguredCachesProperties;
3838
private static readonly INHibernateLogger Log;
39+
3940
/// <summary>
4041
/// The frequency at which scans for cleaning expired cached item have to be done. By default, its value is
4142
/// initialized from <c>expiration-scan-frequency</c> attribute of the <c>corememorycache</c> configuration
@@ -49,7 +50,7 @@ public class CoreMemoryCacheProvider : ICacheProvider
4950
/// For this property to be taken into account, it must be set before any cache is built.
5051
/// </para>
5152
/// <para>
52-
/// If <c>cache.expiration_scan_frequency</c> is provided as an integer, this integer will be used as a number
53+
/// If <c>expiration-scan-frequency</c> is provided as an integer, this integer will be used as a number
5354
/// of minutes. Otherwise the setting will be parsed as a <see cref="TimeSpan" />.
5455
/// </para>
5556
/// </remarks>
@@ -60,26 +61,23 @@ static CoreMemoryCacheProvider()
6061
Log = NHibernateLogger.For(typeof(CoreMemoryCacheProvider));
6162
ConfiguredCachesProperties = new Dictionary<string, IDictionary<string, string>>();
6263

63-
if (!(ConfigurationManager.GetSection("corememorycache") is CacheConfig[] list))
64+
if (!(ConfigurationManager.GetSection("corememorycache") is CacheConfig config))
6465
return;
65-
foreach (var cache in list)
66+
67+
if (config.ExpirationScanFrequency != null)
6668
{
67-
if (cache.Global)
68-
{
69-
if (cache.ExpirationScanFrequency != null)
70-
{
71-
if (int.TryParse(cache.ExpirationScanFrequency, out var minutes))
72-
ExpirationScanFrequency = TimeSpan.FromMinutes(minutes);
73-
else if (TimeSpan.TryParse(cache.ExpirationScanFrequency, out var expirationScanFrequency))
74-
ExpirationScanFrequency = expirationScanFrequency;
75-
if (!ExpirationScanFrequency.HasValue)
76-
Log.Warn(
77-
"Invalid value '{0}' for cache.expiration_scan_frequency setting: it is neither an int nor a TimeSpan. Ignoring.",
78-
cache.ExpirationScanFrequency);
79-
}
80-
continue;
81-
}
69+
if (int.TryParse(config.ExpirationScanFrequency, out var minutes))
70+
ExpirationScanFrequency = TimeSpan.FromMinutes(minutes);
71+
else if (TimeSpan.TryParse(config.ExpirationScanFrequency, out var expirationScanFrequency))
72+
ExpirationScanFrequency = expirationScanFrequency;
73+
if (!ExpirationScanFrequency.HasValue)
74+
Log.Warn(
75+
"Invalid value '{0}' for expiration-scan-frequency setting: it is neither an int nor a TimeSpan. Ignoring.",
76+
config.ExpirationScanFrequency);
77+
}
8278

79+
foreach (var cache in config.Regions)
80+
{
8381
ConfiguredCachesProperties.Add(cache.Region, cache.Properties);
8482
}
8583
}
@@ -94,7 +92,8 @@ public ICache BuildCache(string regionName, IDictionary<string, string> properti
9492
regionName = string.Empty;
9593
}
9694

97-
if (ConfiguredCachesProperties.TryGetValue(regionName, out var configuredProperties) && configuredProperties.Count > 0)
95+
if (ConfiguredCachesProperties.TryGetValue(regionName, out var configuredProperties) &&
96+
configuredProperties.Count > 0)
9897
{
9998
if (properties != null)
10099
{
@@ -130,8 +129,9 @@ public ICache BuildCache(string regionName, IDictionary<string, string> properti
130129
sb.Append(";");
131130
}
132131

133-
Log.Debug("building cache with region: {0}, properties: {1}" , regionName, sb.ToString());
132+
Log.Debug("building cache with region: {0}, properties: {1}", regionName, sb.ToString());
134133
}
134+
135135
return new CoreMemoryCache(regionName, properties);
136136
}
137137

CoreMemoryCache/NHibernate.Caches.CoreMemoryCache/CoreMemoryCacheSectionHandler.cs

Lines changed: 10 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -19,49 +19,30 @@ public class CoreMemoryCacheSectionHandler : IConfigurationSectionHandler
1919
/// <param name="parent"></param>
2020
/// <param name="configContext"></param>
2121
/// <param name="section"></param>
22-
/// <returns>An array of CacheConfig objects.</returns>
22+
/// <returns>A <see cref="CacheConfig" /> object.</returns>
2323
public object Create(object parent, object configContext, XmlNode section)
2424
{
25-
var caches = new List<CacheConfig>();
25+
var caches = new List<RegionConfig>();
2626

27-
var esf = section.Attributes?["expiration-scan-frequency"];
28-
if (esf != null)
29-
{
30-
caches.Add(new CacheConfig(esf.Value));
31-
}
32-
3327
var nodes = section.SelectNodes("cache");
3428
foreach (XmlNode node in nodes)
3529
{
36-
string region = null;
37-
string expiration = null;
38-
string sliding = null;
39-
var r = node.Attributes["region"];
40-
var e = node.Attributes["expiration"];
41-
var s = node.Attributes["sliding"];
42-
if (r != null)
43-
{
44-
region = r.Value;
45-
}
46-
if (e != null)
47-
{
48-
expiration = e.Value;
49-
}
50-
if (s != null)
51-
{
52-
sliding = s.Value;
53-
}
30+
var region = node.Attributes["region"]?.Value;
31+
var expiration = node.Attributes["expiration"]?.Value;
32+
var sliding = node.Attributes["sliding"]?.Value;
5433
if (region != null)
5534
{
56-
caches.Add(new CacheConfig(region, expiration, sliding));
35+
caches.Add(new RegionConfig(region, expiration, sliding));
5736
}
5837
else
5938
{
60-
Log.Warn("Found a cache node lacking a region name: ignored. Node: {0}",
39+
Log.Warn("Found a cache region node lacking a region name: ignored. Node: {0}",
6140
node.OuterXml);
6241
}
6342
}
64-
return caches.ToArray();
43+
44+
var esf = section.Attributes?["expiration-scan-frequency"]?.Value;
45+
return new CacheConfig(esf, caches.ToArray());
6546
}
6647

6748
#endregion

0 commit comments

Comments
 (0)