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:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user