Fixes issue with runtime cache provider when retrieving all items of a certain type, we were sending back an array of nulls if the cache was expired.

This commit is contained in:
Shannon
2013-09-18 17:44:25 +10:00
parent a027c3cb22
commit 95df28bf64
2 changed files with 73 additions and 19 deletions

View File

@@ -59,23 +59,41 @@ namespace Umbraco.Core.Persistence.Caching
var item = _memoryCache != null
? _memoryCache.Get(key)
: HttpRuntime.Cache.Get(key);
return item as IEntity;
var result = item as IEntity;
if (result == null)
{
//ensure the key doesn't exist anymore in the tracker
_keyTracker.Remove(key);
}
return result;
}
public IEnumerable<IEntity> GetByIds(Type type, List<Guid> ids)
{
var collection = new List<IEntity>();
foreach (var guid in ids)
{
var key = GetCompositeId(type, guid);
var item = _memoryCache != null
? _memoryCache.Get(GetCompositeId(type, guid))
: HttpRuntime.Cache.Get(GetCompositeId(type, guid));
yield return item as IEntity;
? _memoryCache.Get(key)
: HttpRuntime.Cache.Get(key);
var result = item as IEntity;
if (result == null)
{
//ensure the key doesn't exist anymore in the tracker
_keyTracker.Remove(key);
}
else
{
collection.Add(result);
}
}
return collection;
}
public IEnumerable<IEntity> GetAllByType(Type type)
{
var collection = new List<IEntity>();
foreach (var key in _keyTracker)
{
if (key.StartsWith(string.Format("{0}{1}-", CacheItemPrefix, type.Name)))
@@ -84,9 +102,19 @@ namespace Umbraco.Core.Persistence.Caching
? _memoryCache.Get(key)
: HttpRuntime.Cache.Get(key);
yield return item as IEntity;
var result = item as IEntity;
if (result == null)
{
//ensure the key doesn't exist anymore in the tracker
_keyTracker.Remove(key);
}
else
{
collection.Add(result);
}
}
}
return collection;
}
public void Save(Type type, IEntity entity)
@@ -159,21 +187,27 @@ namespace Umbraco.Core.Persistence.Caching
{
_keyTracker.Clear();
if (_memoryCache != null)
ClearDataCache();
}
}
//DO not call this unless it's for testing since it clears the data cached but not the keys
internal void ClearDataCache()
{
if (_memoryCache != null)
{
_memoryCache.DisposeIfDisposable();
_memoryCache = new MemoryCache("in-memory");
}
else
{
foreach (DictionaryEntry c in HttpRuntime.Cache)
{
_memoryCache.DisposeIfDisposable();
_memoryCache = new MemoryCache("in-memory");
}
else
{
foreach (DictionaryEntry c in HttpRuntime.Cache)
if (c.Key is string && ((string)c.Key).InvariantStartsWith(CacheItemPrefix))
{
if (c.Key is string && ((string)c.Key).InvariantStartsWith(CacheItemPrefix))
{
if (HttpRuntime.Cache[(string)c.Key] == null) return;
HttpRuntime.Cache.Remove((string)c.Key);
}
}
if (HttpRuntime.Cache[(string)c.Key] == null) return;
HttpRuntime.Cache.Remove((string)c.Key);
}
}
}
}

View File

@@ -34,6 +34,26 @@ namespace Umbraco.Tests.Persistence.Caching
_registry.Save(typeof(MockedEntity), entity6);
}
[Test]
public void Tracked_Keys_Removed_When_Cache_Removed()
{
_registry = RuntimeCacheProvider.Current;
//Fill the registry with random entities
var entity1 = new MockedEntity { Id = 1, Key = 1.ToGuid(), Alias = "mocked1", Name = "Mocked1", Value = Guid.NewGuid().ToString("n") };
var entity2 = new MockedEntity { Id = 2, Key = 2.ToGuid(), Alias = "mocked2", Name = "Mocked2", Value = Guid.NewGuid().ToString("n") };
var entity3 = new MockedEntity { Id = 3, Key = 3.ToGuid(), Alias = "mocked3", Name = "Mocked3", Value = Guid.NewGuid().ToString("n") };
_registry.Save(typeof(MockedEntity), entity1);
_registry.Save(typeof(MockedEntity), entity2);
_registry.Save(typeof(MockedEntity), entity3);
//now clear the runtime cache internally
((RuntimeCacheProvider)_registry).ClearDataCache();
Assert.AreEqual(0, _registry.GetAllByType(typeof (MockedEntity)).Count());
}
[Test]
public void Can_Clear_By_Type()
{