Great AppCaches renaming
This commit is contained in:
@@ -4,47 +4,41 @@ using System.Web;
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the application-wide caches.
|
||||
/// Represents the application caches.
|
||||
/// </summary>
|
||||
public class AppCaches
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance for use in the web
|
||||
/// Initializes a new instance of the <see cref="AppCaches"/> for use in a web application.
|
||||
/// </summary>
|
||||
public AppCaches()
|
||||
: this(
|
||||
new HttpRuntimeCacheProvider(HttpRuntime.Cache),
|
||||
new StaticCacheProvider(),
|
||||
new HttpRequestCacheProvider(),
|
||||
new IsolatedRuntimeCache(t => new ObjectCacheRuntimeCacheProvider()))
|
||||
{
|
||||
}
|
||||
: this(HttpRuntime.Cache)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance for use in the web
|
||||
/// Initializes a new instance of the <see cref="AppCaches"/> for use in a web application.
|
||||
/// </summary>
|
||||
public AppCaches(System.Web.Caching.Cache cache)
|
||||
: this(
|
||||
new HttpRuntimeCacheProvider(cache),
|
||||
new StaticCacheProvider(),
|
||||
new HttpRequestCacheProvider(),
|
||||
new IsolatedRuntimeCache(t => new ObjectCacheRuntimeCacheProvider()))
|
||||
{
|
||||
}
|
||||
new WebCachingAppCache(cache),
|
||||
new DictionaryCacheProvider(),
|
||||
new HttpRequestAppCache(),
|
||||
new IsolatedCaches(t => new ObjectCacheAppCache()))
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance based on the provided providers
|
||||
/// Initializes a new instance of the <see cref="AppCaches"/> with cache providers.
|
||||
/// </summary>
|
||||
public AppCaches(
|
||||
IRuntimeCacheProvider httpCacheProvider,
|
||||
ICacheProvider staticCacheProvider,
|
||||
ICacheProvider requestCacheProvider,
|
||||
IsolatedRuntimeCache isolatedCacheManager)
|
||||
IAppPolicedCache runtimeCache,
|
||||
IAppCache staticCacheProvider,
|
||||
IAppCache requestCache,
|
||||
IsolatedCaches isolatedCaches)
|
||||
{
|
||||
RuntimeCache = httpCacheProvider ?? throw new ArgumentNullException(nameof(httpCacheProvider));
|
||||
RuntimeCache = runtimeCache ?? throw new ArgumentNullException(nameof(runtimeCache));
|
||||
StaticCache = staticCacheProvider ?? throw new ArgumentNullException(nameof(staticCacheProvider));
|
||||
RequestCache = requestCacheProvider ?? throw new ArgumentNullException(nameof(requestCacheProvider));
|
||||
IsolatedRuntimeCache = isolatedCacheManager ?? throw new ArgumentNullException(nameof(isolatedCacheManager));
|
||||
RequestCache = requestCache ?? throw new ArgumentNullException(nameof(requestCache));
|
||||
IsolatedCaches = isolatedCaches ?? throw new ArgumentNullException(nameof(isolatedCaches));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -54,7 +48,7 @@ namespace Umbraco.Core.Cache
|
||||
/// <para>When used by repositories, all cache policies apply, but the underlying caches do not cache anything.</para>
|
||||
/// <para>Used by tests.</para>
|
||||
/// </remarks>
|
||||
public static AppCaches Disabled { get; } = new AppCaches(NullCacheProvider.Instance, NullCacheProvider.Instance, NullCacheProvider.Instance, new IsolatedRuntimeCache(_ => NullCacheProvider.Instance));
|
||||
public static AppCaches Disabled { get; } = new AppCaches(NoAppCache.Instance, NoAppCache.Instance, NoAppCache.Instance, new IsolatedCaches(_ => NoAppCache.Instance));
|
||||
|
||||
/// <summary>
|
||||
/// Gets the special no-cache instance.
|
||||
@@ -63,27 +57,42 @@ namespace Umbraco.Core.Cache
|
||||
/// <para>When used by repositories, all cache policies are bypassed.</para>
|
||||
/// <para>Used by repositories that do no cache.</para>
|
||||
/// </remarks>
|
||||
public static AppCaches NoCache { get; } = new AppCaches(NullCacheProvider.Instance, NullCacheProvider.Instance, NullCacheProvider.Instance, new IsolatedRuntimeCache(_ => NullCacheProvider.Instance));
|
||||
public static AppCaches NoCache { get; } = new AppCaches(NoAppCache.Instance, NoAppCache.Instance, NoAppCache.Instance, new IsolatedCaches(_ => NoAppCache.Instance));
|
||||
|
||||
/// <summary>
|
||||
/// Returns the current Request cache
|
||||
/// Gets the per-request cache.
|
||||
/// </summary>
|
||||
public ICacheProvider RequestCache { get; internal set; }
|
||||
/// <remarks>
|
||||
/// <para>The per-request caches works on top of the current HttpContext items.</para>
|
||||
/// fixme - what about non-web applications?
|
||||
/// </remarks>
|
||||
public IAppCache RequestCache { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the current Runtime cache
|
||||
/// </summary>
|
||||
public ICacheProvider StaticCache { get; internal set; }
|
||||
/// <remarks>
|
||||
/// fixme - what is this? why not use RuntimeCache?
|
||||
/// </remarks>
|
||||
public IAppCache StaticCache { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the current Runtime cache
|
||||
/// Gets the runtime cache.
|
||||
/// </summary>
|
||||
public IRuntimeCacheProvider RuntimeCache { get; internal set; }
|
||||
/// <remarks>
|
||||
/// <para>The runtime cache is the main application cache.</para>
|
||||
/// </remarks>
|
||||
public IAppPolicedCache RuntimeCache { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the current Isolated Runtime cache manager
|
||||
/// Gets the isolated caches.
|
||||
/// </summary>
|
||||
public IsolatedRuntimeCache IsolatedRuntimeCache { get; internal set; }
|
||||
/// <remarks>
|
||||
/// <para>Isolated caches are used by e.g. repositories, to ensure that each cached entity
|
||||
/// type has its own cache, so that lookups are fast and the repository does not need to
|
||||
/// search through all keys on a global scale.</para>
|
||||
/// </remarks>
|
||||
public IsolatedCaches IsolatedCaches { get; }
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides a base class for implementing a dictionary of <see cref="IAppPolicedCache"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="TKey">The type of the dictionary key.</typeparam>
|
||||
public abstract class AppPolicedCacheDictionary<TKey>
|
||||
{
|
||||
private readonly ConcurrentDictionary<TKey, IAppPolicedCache> _caches = new ConcurrentDictionary<TKey, IAppPolicedCache>();
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AppPolicedCacheDictionary{TKey}"/> class.
|
||||
/// </summary>
|
||||
/// <param name="cacheFactory"></param>
|
||||
protected AppPolicedCacheDictionary(Func<TKey, IAppPolicedCache> cacheFactory)
|
||||
{
|
||||
CacheFactory = cacheFactory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the internal cache factory, for tests only!
|
||||
/// </summary>
|
||||
internal readonly Func<TKey, IAppPolicedCache> CacheFactory;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or creates a cache.
|
||||
/// </summary>
|
||||
public IAppPolicedCache GetOrCreate(TKey key)
|
||||
=> _caches.GetOrAdd(key, k => CacheFactory(k));
|
||||
|
||||
/// <summary>
|
||||
/// Tries to get a cache.
|
||||
/// </summary>
|
||||
public Attempt<IAppPolicedCache> Get(TKey key)
|
||||
=> _caches.TryGetValue(key, out var cache) ? Attempt.Succeed(cache) : Attempt.Fail<IAppPolicedCache>();
|
||||
|
||||
/// <summary>
|
||||
/// Removes a cache.
|
||||
/// </summary>
|
||||
public void Remove(TKey key)
|
||||
{
|
||||
_caches.TryRemove(key, out _);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes all caches.
|
||||
/// </summary>
|
||||
public void RemoveAll()
|
||||
{
|
||||
_caches.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears a cache.
|
||||
/// </summary>
|
||||
public void ClearCache(TKey key)
|
||||
{
|
||||
if (_caches.TryGetValue(key, out var cache))
|
||||
cache.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears all caches.
|
||||
/// </summary>
|
||||
public void ClearAllCaches()
|
||||
{
|
||||
foreach (var cache in _caches.Values)
|
||||
cache.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ namespace Umbraco.Core.Cache
|
||||
/// </summary>
|
||||
public static class CacheProviderExtensions
|
||||
{
|
||||
public static T GetCacheItem<T>(this IRuntimeCacheProvider provider,
|
||||
public static T GetCacheItem<T>(this IAppPolicedCache provider,
|
||||
string cacheKey,
|
||||
Func<T> getCacheItem,
|
||||
TimeSpan? timeout,
|
||||
@@ -19,11 +19,11 @@ namespace Umbraco.Core.Cache
|
||||
CacheItemRemovedCallback removedCallback = null,
|
||||
string[] dependentFiles = null)
|
||||
{
|
||||
var result = provider.GetCacheItem(cacheKey, () => getCacheItem(), timeout, isSliding, priority, removedCallback, dependentFiles);
|
||||
var result = provider.Get(cacheKey, () => getCacheItem(), timeout, isSliding, priority, removedCallback, dependentFiles);
|
||||
return result == null ? default(T) : result.TryConvertTo<T>().Result;
|
||||
}
|
||||
|
||||
public static void InsertCacheItem<T>(this IRuntimeCacheProvider provider,
|
||||
public static void InsertCacheItem<T>(this IAppPolicedCache provider,
|
||||
string cacheKey,
|
||||
Func<T> getCacheItem,
|
||||
TimeSpan? timeout = null,
|
||||
@@ -32,24 +32,24 @@ namespace Umbraco.Core.Cache
|
||||
CacheItemRemovedCallback removedCallback = null,
|
||||
string[] dependentFiles = null)
|
||||
{
|
||||
provider.InsertCacheItem(cacheKey, () => getCacheItem(), timeout, isSliding, priority, removedCallback, dependentFiles);
|
||||
provider.Insert(cacheKey, () => getCacheItem(), timeout, isSliding, priority, removedCallback, dependentFiles);
|
||||
}
|
||||
|
||||
public static IEnumerable<T> GetCacheItemsByKeySearch<T>(this ICacheProvider provider, string keyStartsWith)
|
||||
public static IEnumerable<T> GetCacheItemsByKeySearch<T>(this IAppCache provider, string keyStartsWith)
|
||||
{
|
||||
var result = provider.GetCacheItemsByKeySearch(keyStartsWith);
|
||||
var result = provider.SearchByKey(keyStartsWith);
|
||||
return result.Select(x => x.TryConvertTo<T>().Result);
|
||||
}
|
||||
|
||||
public static IEnumerable<T> GetCacheItemsByKeyExpression<T>(this ICacheProvider provider, string regexString)
|
||||
public static IEnumerable<T> GetCacheItemsByKeyExpression<T>(this IAppCache provider, string regexString)
|
||||
{
|
||||
var result = provider.GetCacheItemsByKeyExpression(regexString);
|
||||
var result = provider.SearchByRegex(regexString);
|
||||
return result.Select(x => x.TryConvertTo<T>().Result);
|
||||
}
|
||||
|
||||
public static T GetCacheItem<T>(this ICacheProvider provider, string cacheKey)
|
||||
public static T GetCacheItem<T>(this IAppCache provider, string cacheKey)
|
||||
{
|
||||
var result = provider.GetCacheItem(cacheKey);
|
||||
var result = provider.Get(cacheKey);
|
||||
if (result == null)
|
||||
{
|
||||
return default(T);
|
||||
@@ -57,9 +57,9 @@ namespace Umbraco.Core.Cache
|
||||
return result.TryConvertTo<T>().Result;
|
||||
}
|
||||
|
||||
public static T GetCacheItem<T>(this ICacheProvider provider, string cacheKey, Func<T> getCacheItem)
|
||||
public static T GetCacheItem<T>(this IAppCache provider, string cacheKey, Func<T> getCacheItem)
|
||||
{
|
||||
var result = provider.GetCacheItem(cacheKey, () => getCacheItem());
|
||||
var result = provider.Get(cacheKey, () => getCacheItem());
|
||||
if (result == null)
|
||||
{
|
||||
return default(T);
|
||||
|
||||
@@ -102,7 +102,7 @@ namespace Umbraco.Core.Cache
|
||||
protected void ClearAllIsolatedCacheByEntityType<TEntity>()
|
||||
where TEntity : class, IEntity
|
||||
{
|
||||
AppCaches.IsolatedRuntimeCache.ClearCache<TEntity>();
|
||||
AppCaches.IsolatedCaches.ClearCache<TEntity>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web.Caching;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Entities;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// Implements <see cref="IAppPolicedCache"/> by wrapping an inner other <see cref="IAppPolicedCache"/>
|
||||
/// instance, and ensuring that all inserts and returns are deep cloned copies of the cache item,
|
||||
/// when the item is deep-cloneable.
|
||||
/// </summary>
|
||||
internal class DeepCloneAppCache : IAppPolicedCache
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DeepCloneAppCache"/> class.
|
||||
/// </summary>
|
||||
public DeepCloneAppCache(IAppPolicedCache innerCache)
|
||||
{
|
||||
var type = typeof (DeepCloneAppCache);
|
||||
|
||||
if (innerCache.GetType() == type)
|
||||
throw new InvalidOperationException($"A {type} cannot wrap another instance of itself.");
|
||||
|
||||
InnerCache = innerCache;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the inner cache.
|
||||
/// </summary>
|
||||
public IAppPolicedCache InnerCache { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public object Get(string key)
|
||||
{
|
||||
var item = InnerCache.Get(key);
|
||||
return CheckCloneableAndTracksChanges(item);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public object Get(string key, Func<object> factory)
|
||||
{
|
||||
var cached = InnerCache.Get(key, () =>
|
||||
{
|
||||
var result = FastDictionaryAppCacheBase.GetSafeLazy(factory);
|
||||
var value = result.Value; // force evaluation now - this may throw if cacheItem throws, and then nothing goes into cache
|
||||
// do not store null values (backward compat), clone / reset to go into the cache
|
||||
return value == null ? null : CheckCloneableAndTracksChanges(value);
|
||||
});
|
||||
return CheckCloneableAndTracksChanges(cached);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<object> SearchByKey(string keyStartsWith)
|
||||
{
|
||||
return InnerCache.SearchByKey(keyStartsWith)
|
||||
.Select(CheckCloneableAndTracksChanges);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<object> SearchByRegex(string regex)
|
||||
{
|
||||
return InnerCache.SearchByRegex(regex)
|
||||
.Select(CheckCloneableAndTracksChanges);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public object Get(string key, Func<object> factory, TimeSpan? timeout, bool isSliding = false, CacheItemPriority priority = CacheItemPriority.Normal, CacheItemRemovedCallback removedCallback = null, string[] dependentFiles = null)
|
||||
{
|
||||
var cached = InnerCache.Get(key, () =>
|
||||
{
|
||||
var result = FastDictionaryAppCacheBase.GetSafeLazy(factory);
|
||||
var value = result.Value; // force evaluation now - this may throw if cacheItem throws, and then nothing goes into cache
|
||||
// do not store null values (backward compat), clone / reset to go into the cache
|
||||
return value == null ? null : CheckCloneableAndTracksChanges(value);
|
||||
|
||||
// clone / reset to go into the cache
|
||||
}, timeout, isSliding, priority, removedCallback, dependentFiles);
|
||||
|
||||
// clone / reset to go into the cache
|
||||
return CheckCloneableAndTracksChanges(cached);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Insert(string key, Func<object> factory, TimeSpan? timeout = null, bool isSliding = false, CacheItemPriority priority = CacheItemPriority.Normal, CacheItemRemovedCallback removedCallback = null, string[] dependentFiles = null)
|
||||
{
|
||||
InnerCache.Insert(key, () =>
|
||||
{
|
||||
var result = FastDictionaryAppCacheBase.GetSafeLazy(factory);
|
||||
var value = result.Value; // force evaluation now - this may throw if cacheItem throws, and then nothing goes into cache
|
||||
// do not store null values (backward compat), clone / reset to go into the cache
|
||||
return value == null ? null : CheckCloneableAndTracksChanges(value);
|
||||
}, timeout, isSliding, priority, removedCallback, dependentFiles);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Clear()
|
||||
{
|
||||
InnerCache.Clear();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Clear(string key)
|
||||
{
|
||||
InnerCache.Clear(key);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void ClearOfType(string typeName)
|
||||
{
|
||||
InnerCache.ClearOfType(typeName);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void ClearOfType<T>()
|
||||
{
|
||||
InnerCache.ClearOfType<T>();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void ClearOfType<T>(Func<string, T, bool> predicate)
|
||||
{
|
||||
InnerCache.ClearOfType<T>(predicate);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void ClearByKey(string keyStartsWith)
|
||||
{
|
||||
InnerCache.ClearByKey(keyStartsWith);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void ClearByRegex(string regex)
|
||||
{
|
||||
InnerCache.ClearByRegex(regex);
|
||||
}
|
||||
|
||||
private static object CheckCloneableAndTracksChanges(object input)
|
||||
{
|
||||
if (input is IDeepCloneable cloneable)
|
||||
{
|
||||
input = cloneable.DeepClone();
|
||||
}
|
||||
|
||||
// reset dirty initial properties
|
||||
if (input is IRememberBeingDirty tracksChanges)
|
||||
{
|
||||
tracksChanges.ResetDirtyProperties(false);
|
||||
input = tracksChanges;
|
||||
}
|
||||
|
||||
return input;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,155 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web.Caching;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Entities;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface describing this cache provider as a wrapper for another
|
||||
/// </summary>
|
||||
internal interface IRuntimeCacheProviderWrapper
|
||||
{
|
||||
IRuntimeCacheProvider InnerProvider { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A wrapper for any IRuntimeCacheProvider that ensures that all inserts and returns
|
||||
/// are a deep cloned copy of the item when the item is IDeepCloneable and that tracks changes are
|
||||
/// reset if the object is TracksChangesEntityBase
|
||||
/// </summary>
|
||||
internal class DeepCloneRuntimeCacheProvider : IRuntimeCacheProvider, IRuntimeCacheProviderWrapper
|
||||
{
|
||||
public IRuntimeCacheProvider InnerProvider { get; }
|
||||
|
||||
public DeepCloneRuntimeCacheProvider(IRuntimeCacheProvider innerProvider)
|
||||
{
|
||||
var type = typeof (DeepCloneRuntimeCacheProvider);
|
||||
|
||||
if (innerProvider.GetType() == type)
|
||||
throw new InvalidOperationException($"A {type} cannot wrap another instance of {type}.");
|
||||
|
||||
InnerProvider = innerProvider;
|
||||
}
|
||||
|
||||
#region Clear - doesn't require any changes
|
||||
|
||||
public void ClearAllCache()
|
||||
{
|
||||
InnerProvider.ClearAllCache();
|
||||
}
|
||||
|
||||
public void ClearCacheItem(string key)
|
||||
{
|
||||
InnerProvider.ClearCacheItem(key);
|
||||
}
|
||||
|
||||
public void ClearCacheObjectTypes(string typeName)
|
||||
{
|
||||
InnerProvider.ClearCacheObjectTypes(typeName);
|
||||
}
|
||||
|
||||
public void ClearCacheObjectTypes<T>()
|
||||
{
|
||||
InnerProvider.ClearCacheObjectTypes<T>();
|
||||
}
|
||||
|
||||
public void ClearCacheObjectTypes<T>(Func<string, T, bool> predicate)
|
||||
{
|
||||
InnerProvider.ClearCacheObjectTypes<T>(predicate);
|
||||
}
|
||||
|
||||
public void ClearCacheByKeySearch(string keyStartsWith)
|
||||
{
|
||||
InnerProvider.ClearCacheByKeySearch(keyStartsWith);
|
||||
}
|
||||
|
||||
public void ClearCacheByKeyExpression(string regexString)
|
||||
{
|
||||
InnerProvider.ClearCacheByKeyExpression(regexString);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public IEnumerable<object> GetCacheItemsByKeySearch(string keyStartsWith)
|
||||
{
|
||||
return InnerProvider.GetCacheItemsByKeySearch(keyStartsWith)
|
||||
.Select(CheckCloneableAndTracksChanges);
|
||||
}
|
||||
|
||||
public IEnumerable<object> GetCacheItemsByKeyExpression(string regexString)
|
||||
{
|
||||
return InnerProvider.GetCacheItemsByKeyExpression(regexString)
|
||||
.Select(CheckCloneableAndTracksChanges);
|
||||
}
|
||||
|
||||
public object GetCacheItem(string cacheKey)
|
||||
{
|
||||
var item = InnerProvider.GetCacheItem(cacheKey);
|
||||
return CheckCloneableAndTracksChanges(item);
|
||||
}
|
||||
|
||||
public object GetCacheItem(string cacheKey, Func<object> getCacheItem)
|
||||
{
|
||||
var cached = InnerProvider.GetCacheItem(cacheKey, () =>
|
||||
{
|
||||
var result = DictionaryCacheProviderBase.GetSafeLazy(getCacheItem);
|
||||
var value = result.Value; // force evaluation now - this may throw if cacheItem throws, and then nothing goes into cache
|
||||
if (value == null) return null; // do not store null values (backward compat)
|
||||
|
||||
return CheckCloneableAndTracksChanges(value);
|
||||
});
|
||||
return CheckCloneableAndTracksChanges(cached);
|
||||
}
|
||||
|
||||
public object GetCacheItem(string cacheKey, Func<object> getCacheItem, TimeSpan? timeout, bool isSliding = false, CacheItemPriority priority = CacheItemPriority.Normal, CacheItemRemovedCallback removedCallback = null, string[] dependentFiles = null)
|
||||
{
|
||||
var cached = InnerProvider.GetCacheItem(cacheKey, () =>
|
||||
{
|
||||
var result = DictionaryCacheProviderBase.GetSafeLazy(getCacheItem);
|
||||
var value = result.Value; // force evaluation now - this may throw if cacheItem throws, and then nothing goes into cache
|
||||
if (value == null) return null; // do not store null values (backward compat)
|
||||
|
||||
// clone / reset to go into the cache
|
||||
return CheckCloneableAndTracksChanges(value);
|
||||
}, timeout, isSliding, priority, removedCallback, dependentFiles);
|
||||
|
||||
// clone / reset to go into the cache
|
||||
return CheckCloneableAndTracksChanges(cached);
|
||||
}
|
||||
|
||||
public void InsertCacheItem(string cacheKey, Func<object> getCacheItem, TimeSpan? timeout = null, bool isSliding = false, CacheItemPriority priority = CacheItemPriority.Normal, CacheItemRemovedCallback removedCallback = null, string[] dependentFiles = null)
|
||||
{
|
||||
InnerProvider.InsertCacheItem(cacheKey, () =>
|
||||
{
|
||||
var result = DictionaryCacheProviderBase.GetSafeLazy(getCacheItem);
|
||||
var value = result.Value; // force evaluation now - this may throw if cacheItem throws, and then nothing goes into cache
|
||||
if (value == null) return null; // do not store null values (backward compat)
|
||||
|
||||
// clone / reset to go into the cache
|
||||
return CheckCloneableAndTracksChanges(value);
|
||||
}, timeout, isSliding, priority, removedCallback, dependentFiles);
|
||||
}
|
||||
|
||||
private static object CheckCloneableAndTracksChanges(object input)
|
||||
{
|
||||
var cloneable = input as IDeepCloneable;
|
||||
if (cloneable != null)
|
||||
{
|
||||
input = cloneable.DeepClone();
|
||||
}
|
||||
|
||||
// reset dirty initial properties (U4-1946)
|
||||
var tracksChanges = input as IRememberBeingDirty;
|
||||
if (tracksChanges != null)
|
||||
{
|
||||
tracksChanges.ResetDirtyProperties(false);
|
||||
input = tracksChanges;
|
||||
}
|
||||
|
||||
return input;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,7 @@ namespace Umbraco.Core.Cache
|
||||
private static readonly TEntity[] EmptyEntities = new TEntity[0]; // const
|
||||
private readonly RepositoryCachePolicyOptions _options;
|
||||
|
||||
public DefaultRepositoryCachePolicy(IRuntimeCacheProvider cache, IScopeAccessor scopeAccessor, RepositoryCachePolicyOptions options)
|
||||
public DefaultRepositoryCachePolicy(IAppPolicedCache cache, IScopeAccessor scopeAccessor, RepositoryCachePolicyOptions options)
|
||||
: base(cache, scopeAccessor)
|
||||
{
|
||||
_options = options ?? throw new ArgumentNullException(nameof(options));
|
||||
@@ -42,7 +42,7 @@ namespace Umbraco.Core.Cache
|
||||
|
||||
protected virtual void InsertEntity(string cacheKey, TEntity entity)
|
||||
{
|
||||
Cache.InsertCacheItem(cacheKey, () => entity, TimeSpan.FromMinutes(5), true);
|
||||
Cache.Insert(cacheKey, () => entity, TimeSpan.FromMinutes(5), true);
|
||||
}
|
||||
|
||||
protected virtual void InsertEntities(TId[] ids, TEntity[] entities)
|
||||
@@ -52,7 +52,7 @@ namespace Umbraco.Core.Cache
|
||||
// getting all of them, and finding nothing.
|
||||
// if we can cache a zero count, cache an empty array,
|
||||
// for as long as the cache is not cleared (no expiration)
|
||||
Cache.InsertCacheItem(GetEntityTypeCacheKey(), () => EmptyEntities);
|
||||
Cache.Insert(GetEntityTypeCacheKey(), () => EmptyEntities);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -60,7 +60,7 @@ namespace Umbraco.Core.Cache
|
||||
foreach (var entity in entities)
|
||||
{
|
||||
var capture = entity;
|
||||
Cache.InsertCacheItem(GetEntityCacheKey(entity.Id), () => capture, TimeSpan.FromMinutes(5), true);
|
||||
Cache.Insert(GetEntityCacheKey(entity.Id), () => capture, TimeSpan.FromMinutes(5), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -77,21 +77,21 @@ namespace Umbraco.Core.Cache
|
||||
// just to be safe, we cannot cache an item without an identity
|
||||
if (entity.HasIdentity)
|
||||
{
|
||||
Cache.InsertCacheItem(GetEntityCacheKey(entity.Id), () => entity, TimeSpan.FromMinutes(5), true);
|
||||
Cache.Insert(GetEntityCacheKey(entity.Id), () => entity, TimeSpan.FromMinutes(5), true);
|
||||
}
|
||||
|
||||
// if there's a GetAllCacheAllowZeroCount cache, ensure it is cleared
|
||||
Cache.ClearCacheItem(GetEntityTypeCacheKey());
|
||||
Cache.Clear(GetEntityTypeCacheKey());
|
||||
}
|
||||
catch
|
||||
{
|
||||
// if an exception is thrown we need to remove the entry from cache,
|
||||
// this is ONLY a work around because of the way
|
||||
// that we cache entities: http://issues.umbraco.org/issue/U4-4259
|
||||
Cache.ClearCacheItem(GetEntityCacheKey(entity.Id));
|
||||
Cache.Clear(GetEntityCacheKey(entity.Id));
|
||||
|
||||
// if there's a GetAllCacheAllowZeroCount cache, ensure it is cleared
|
||||
Cache.ClearCacheItem(GetEntityTypeCacheKey());
|
||||
Cache.Clear(GetEntityTypeCacheKey());
|
||||
|
||||
throw;
|
||||
}
|
||||
@@ -109,21 +109,21 @@ namespace Umbraco.Core.Cache
|
||||
// just to be safe, we cannot cache an item without an identity
|
||||
if (entity.HasIdentity)
|
||||
{
|
||||
Cache.InsertCacheItem(GetEntityCacheKey(entity.Id), () => entity, TimeSpan.FromMinutes(5), true);
|
||||
Cache.Insert(GetEntityCacheKey(entity.Id), () => entity, TimeSpan.FromMinutes(5), true);
|
||||
}
|
||||
|
||||
// if there's a GetAllCacheAllowZeroCount cache, ensure it is cleared
|
||||
Cache.ClearCacheItem(GetEntityTypeCacheKey());
|
||||
Cache.Clear(GetEntityTypeCacheKey());
|
||||
}
|
||||
catch
|
||||
{
|
||||
// if an exception is thrown we need to remove the entry from cache,
|
||||
// this is ONLY a work around because of the way
|
||||
// that we cache entities: http://issues.umbraco.org/issue/U4-4259
|
||||
Cache.ClearCacheItem(GetEntityCacheKey(entity.Id));
|
||||
Cache.Clear(GetEntityCacheKey(entity.Id));
|
||||
|
||||
// if there's a GetAllCacheAllowZeroCount cache, ensure it is cleared
|
||||
Cache.ClearCacheItem(GetEntityTypeCacheKey());
|
||||
Cache.Clear(GetEntityTypeCacheKey());
|
||||
|
||||
throw;
|
||||
}
|
||||
@@ -142,9 +142,9 @@ namespace Umbraco.Core.Cache
|
||||
{
|
||||
// whatever happens, clear the cache
|
||||
var cacheKey = GetEntityCacheKey(entity.Id);
|
||||
Cache.ClearCacheItem(cacheKey);
|
||||
Cache.Clear(cacheKey);
|
||||
// if there's a GetAllCacheAllowZeroCount cache, ensure it is cleared
|
||||
Cache.ClearCacheItem(GetEntityTypeCacheKey());
|
||||
Cache.Clear(GetEntityTypeCacheKey());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -238,7 +238,7 @@ namespace Umbraco.Core.Cache
|
||||
/// <inheritdoc />
|
||||
public override void ClearAll()
|
||||
{
|
||||
Cache.ClearCacheByKeySearch(GetEntityTypeCacheKey());
|
||||
Cache.ClearByKey(GetEntityTypeCacheKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,147 +1,97 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using Umbraco.Core.Composing;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
internal class DictionaryCacheProvider : ICacheProvider
|
||||
/// <summary>
|
||||
/// Implements <see cref="IAppCache"/> on top of a concurrent dictionary.
|
||||
/// </summary>
|
||||
public class DictionaryCacheProvider : IAppCache
|
||||
{
|
||||
private readonly ConcurrentDictionary<string, Lazy<object>> _items
|
||||
= new ConcurrentDictionary<string, Lazy<object>>();
|
||||
/// <summary>
|
||||
/// Gets the internal items dictionary, for tests only!
|
||||
/// </summary>
|
||||
internal readonly ConcurrentDictionary<string, object> Items = new ConcurrentDictionary<string, object>();
|
||||
|
||||
// for tests
|
||||
internal ConcurrentDictionary<string, Lazy<object>> Items => _items;
|
||||
|
||||
public void ClearAllCache()
|
||||
/// <inheritdoc />
|
||||
public virtual object Get(string key)
|
||||
{
|
||||
_items.Clear();
|
||||
// fixme throws if non-existing, shouldn't it return null?
|
||||
return Items[key];
|
||||
}
|
||||
|
||||
public void ClearCacheItem(string key)
|
||||
/// <inheritdoc />
|
||||
public virtual object Get(string key, Func<object> factory)
|
||||
{
|
||||
_items.TryRemove(key, out _);
|
||||
return Items.GetOrAdd(key, _ => factory());
|
||||
}
|
||||
|
||||
public void ClearCacheObjectTypes(string typeName)
|
||||
/// <inheritdoc />
|
||||
public virtual IEnumerable<object> SearchByKey(string keyStartsWith)
|
||||
{
|
||||
var type = TypeFinder.GetTypeByName(typeName);
|
||||
if (type == null) return;
|
||||
var isInterface = type.IsInterface;
|
||||
|
||||
foreach (var kvp in _items
|
||||
.Where(x =>
|
||||
{
|
||||
// entry.Value is Lazy<object> and not null, its value may be null
|
||||
// remove null values as well, does not hurt
|
||||
// get non-created as NonCreatedValue & exceptions as null
|
||||
var value = DictionaryCacheProviderBase.GetSafeLazyValue(x.Value, true);
|
||||
|
||||
// if T is an interface remove anything that implements that interface
|
||||
// otherwise remove exact types (not inherited types)
|
||||
return value == null || (isInterface ? (type.IsInstanceOfType(value)) : (value.GetType() == type));
|
||||
}))
|
||||
_items.TryRemove(kvp.Key, out _);
|
||||
var items = new List<object>();
|
||||
foreach (var (key, value) in Items)
|
||||
if (key.InvariantStartsWith(keyStartsWith))
|
||||
items.Add(value);
|
||||
return items;
|
||||
}
|
||||
|
||||
public void ClearCacheObjectTypes<T>()
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<object> SearchByRegex(string regex)
|
||||
{
|
||||
var compiled = new Regex(regex, RegexOptions.Compiled);
|
||||
var items = new List<object>();
|
||||
foreach (var (key, value) in Items)
|
||||
if (compiled.IsMatch(key))
|
||||
items.Add(value);
|
||||
return items;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual void Clear()
|
||||
{
|
||||
Items.Clear();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual void Clear(string key)
|
||||
{
|
||||
Items.TryRemove(key, out _);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual void ClearOfType(string typeName)
|
||||
{
|
||||
Items.RemoveAll(kvp => kvp.Value != null && kvp.Value.GetType().ToString().InvariantEquals(typeName));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual void ClearOfType<T>()
|
||||
{
|
||||
var typeOfT = typeof(T);
|
||||
var isInterface = typeOfT.IsInterface;
|
||||
|
||||
foreach (var kvp in _items
|
||||
.Where(x =>
|
||||
{
|
||||
// entry.Value is Lazy<object> and not null, its value may be null
|
||||
// remove null values as well, does not hurt
|
||||
// compare on exact type, don't use "is"
|
||||
// get non-created as NonCreatedValue & exceptions as null
|
||||
var value = DictionaryCacheProviderBase.GetSafeLazyValue(x.Value, true);
|
||||
|
||||
// if T is an interface remove anything that implements that interface
|
||||
// otherwise remove exact types (not inherited types)
|
||||
return value == null || (isInterface ? (value is T) : (value.GetType() == typeOfT));
|
||||
}))
|
||||
_items.TryRemove(kvp.Key, out _);
|
||||
Items.RemoveAll(kvp => kvp.Value != null && kvp.Value.GetType() == typeOfT);
|
||||
}
|
||||
|
||||
public void ClearCacheObjectTypes<T>(Func<string, T, bool> predicate)
|
||||
/// <inheritdoc />
|
||||
public virtual void ClearOfType<T>(Func<string, T, bool> predicate)
|
||||
{
|
||||
var typeOfT = typeof(T);
|
||||
var isInterface = typeOfT.IsInterface;
|
||||
|
||||
foreach (var kvp in _items
|
||||
.Where(x =>
|
||||
{
|
||||
// entry.Value is Lazy<object> and not null, its value may be null
|
||||
// remove null values as well, does not hurt
|
||||
// compare on exact type, don't use "is"
|
||||
// get non-created as NonCreatedValue & exceptions as null
|
||||
var value = DictionaryCacheProviderBase.GetSafeLazyValue(x.Value, true);
|
||||
if (value == null) return true;
|
||||
|
||||
// if T is an interface remove anything that implements that interface
|
||||
// otherwise remove exact types (not inherited types)
|
||||
return (isInterface ? (value is T) : (value.GetType() == typeOfT))
|
||||
// run predicate on the 'public key' part only, ie without prefix
|
||||
&& predicate(x.Key, (T)value);
|
||||
}))
|
||||
_items.TryRemove(kvp.Key, out _);
|
||||
Items.RemoveAll(kvp => kvp.Value != null && kvp.Value.GetType() == typeOfT && predicate(kvp.Key, (T)kvp.Value));
|
||||
}
|
||||
|
||||
public void ClearCacheByKeySearch(string keyStartsWith)
|
||||
/// <inheritdoc />
|
||||
public virtual void ClearByKey(string keyStartsWith)
|
||||
{
|
||||
foreach (var ikvp in _items
|
||||
.Where(kvp => kvp.Key.InvariantStartsWith(keyStartsWith)))
|
||||
_items.TryRemove(ikvp.Key, out _);
|
||||
Items.RemoveAll(kvp => kvp.Key.InvariantStartsWith(keyStartsWith));
|
||||
}
|
||||
|
||||
public void ClearCacheByKeyExpression(string regexString)
|
||||
/// <inheritdoc />
|
||||
public virtual void ClearByRegex(string regex)
|
||||
{
|
||||
foreach (var ikvp in _items
|
||||
.Where(kvp => Regex.IsMatch(kvp.Key, regexString)))
|
||||
_items.TryRemove(ikvp.Key, out _);
|
||||
}
|
||||
|
||||
public IEnumerable<object> GetCacheItemsByKeySearch(string keyStartsWith)
|
||||
{
|
||||
return _items
|
||||
.Where(kvp => kvp.Key.InvariantStartsWith(keyStartsWith))
|
||||
.Select(kvp => DictionaryCacheProviderBase.GetSafeLazyValue(kvp.Value))
|
||||
.Where(x => x != null);
|
||||
}
|
||||
|
||||
public IEnumerable<object> GetCacheItemsByKeyExpression(string regexString)
|
||||
{
|
||||
return _items
|
||||
.Where(kvp => Regex.IsMatch(kvp.Key, regexString))
|
||||
.Select(kvp => DictionaryCacheProviderBase.GetSafeLazyValue(kvp.Value))
|
||||
.Where(x => x != null);
|
||||
}
|
||||
|
||||
public object GetCacheItem(string cacheKey)
|
||||
{
|
||||
_items.TryGetValue(cacheKey, out var result); // else null
|
||||
return result == null ? null : DictionaryCacheProviderBase.GetSafeLazyValue(result); // return exceptions as null
|
||||
}
|
||||
|
||||
public object GetCacheItem(string cacheKey, Func<object> getCacheItem)
|
||||
{
|
||||
var result = _items.GetOrAdd(cacheKey, k => DictionaryCacheProviderBase.GetSafeLazy(getCacheItem));
|
||||
|
||||
var value = result.Value; // will not throw (safe lazy)
|
||||
if (!(value is DictionaryCacheProviderBase.ExceptionHolder eh))
|
||||
return value;
|
||||
|
||||
// and... it's in the cache anyway - so contrary to other cache providers,
|
||||
// which would trick with GetSafeLazyValue, we need to remove by ourselves,
|
||||
// in order NOT to cache exceptions
|
||||
|
||||
_items.TryRemove(cacheKey, out result);
|
||||
eh.Exception.Throw(); // throw once!
|
||||
return null; // never reached
|
||||
var compiled = new Regex(regex, RegexOptions.Compiled);
|
||||
Items.RemoveAll(kvp => compiled.IsMatch(kvp.Key));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+129
-113
@@ -8,7 +8,10 @@ using Umbraco.Core.Composing;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
internal abstract class DictionaryCacheProviderBase : ICacheProvider
|
||||
/// <summary>
|
||||
/// Provides a base class to fast, dictionary-based <see cref="IAppCache"/> implementations.
|
||||
/// </summary>
|
||||
internal abstract class FastDictionaryAppCacheBase : IAppCache
|
||||
{
|
||||
// prefix cache keys so we know which one are ours
|
||||
protected const string CacheItemPrefix = "umbrtmche";
|
||||
@@ -16,82 +19,75 @@ namespace Umbraco.Core.Cache
|
||||
// an object that represent a value that has not been created yet
|
||||
protected internal static readonly object ValueNotCreated = new object();
|
||||
|
||||
// manupulate the underlying cache entries
|
||||
// these *must* be called from within the appropriate locks
|
||||
// and use the full prefixed cache keys
|
||||
protected abstract IEnumerable<DictionaryEntry> GetDictionaryEntries();
|
||||
protected abstract void RemoveEntry(string key);
|
||||
protected abstract object GetEntry(string key);
|
||||
#region IAppCache
|
||||
|
||||
// read-write lock the underlying cache
|
||||
//protected abstract IDisposable ReadLock { get; }
|
||||
//protected abstract IDisposable WriteLock { get; }
|
||||
|
||||
protected abstract void EnterReadLock();
|
||||
protected abstract void ExitReadLock();
|
||||
protected abstract void EnterWriteLock();
|
||||
protected abstract void ExitWriteLock();
|
||||
|
||||
protected string GetCacheKey(string key)
|
||||
/// <inheritdoc />
|
||||
public virtual object Get(string key)
|
||||
{
|
||||
return string.Format("{0}-{1}", CacheItemPrefix, key);
|
||||
}
|
||||
|
||||
protected internal static Lazy<object> GetSafeLazy(Func<object> getCacheItem)
|
||||
{
|
||||
// try to generate the value and if it fails,
|
||||
// wrap in an ExceptionHolder - would be much simpler
|
||||
// to just use lazy.IsValueFaulted alas that field is
|
||||
// internal
|
||||
return new Lazy<object>(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
return getCacheItem();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return new ExceptionHolder(ExceptionDispatchInfo.Capture(e));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected internal static object GetSafeLazyValue(Lazy<object> lazy, bool onlyIfValueIsCreated = false)
|
||||
{
|
||||
// if onlyIfValueIsCreated, do not trigger value creation
|
||||
// must return something, though, to differenciate from null values
|
||||
if (onlyIfValueIsCreated && lazy.IsValueCreated == false) return ValueNotCreated;
|
||||
|
||||
// if execution has thrown then lazy.IsValueCreated is false
|
||||
// and lazy.IsValueFaulted is true (but internal) so we use our
|
||||
// own exception holder (see Lazy<T> source code) to return null
|
||||
if (lazy.Value is ExceptionHolder) return null;
|
||||
|
||||
// we have a value and execution has not thrown so returning
|
||||
// here does not throw - unless we're re-entering, take care of it
|
||||
key = GetCacheKey(key);
|
||||
Lazy<object> result;
|
||||
try
|
||||
{
|
||||
return lazy.Value;
|
||||
EnterReadLock();
|
||||
result = GetEntry(key) as Lazy<object>; // null if key not found
|
||||
}
|
||||
catch (InvalidOperationException e)
|
||||
finally
|
||||
{
|
||||
throw new InvalidOperationException("The method that computes a value for the cache has tried to read that value from the cache.", e);
|
||||
ExitReadLock();
|
||||
}
|
||||
return result == null ? null : GetSafeLazyValue(result); // return exceptions as null
|
||||
}
|
||||
|
||||
internal class ExceptionHolder
|
||||
/// <inheritdoc />
|
||||
public abstract object Get(string key, Func<object> factory);
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual IEnumerable<object> SearchByKey(string keyStartsWith)
|
||||
{
|
||||
public ExceptionHolder(ExceptionDispatchInfo e)
|
||||
var plen = CacheItemPrefix.Length + 1;
|
||||
IEnumerable<DictionaryEntry> entries;
|
||||
try
|
||||
{
|
||||
Exception = e;
|
||||
EnterReadLock();
|
||||
entries = GetDictionaryEntries()
|
||||
.Where(x => ((string)x.Key).Substring(plen).InvariantStartsWith(keyStartsWith))
|
||||
.ToArray(); // evaluate while locked
|
||||
}
|
||||
finally
|
||||
{
|
||||
ExitReadLock();
|
||||
}
|
||||
|
||||
public ExceptionDispatchInfo Exception { get; }
|
||||
return entries
|
||||
.Select(x => GetSafeLazyValue((Lazy<object>)x.Value)) // return exceptions as null
|
||||
.Where(x => x != null); // backward compat, don't store null values in the cache
|
||||
}
|
||||
|
||||
#region Clear
|
||||
/// <inheritdoc />
|
||||
public virtual IEnumerable<object> SearchByRegex(string regex)
|
||||
{
|
||||
const string prefix = CacheItemPrefix + "-";
|
||||
var compiled = new Regex(regex, RegexOptions.Compiled);
|
||||
var plen = prefix.Length;
|
||||
IEnumerable<DictionaryEntry> entries;
|
||||
try
|
||||
{
|
||||
EnterReadLock();
|
||||
entries = GetDictionaryEntries()
|
||||
.Where(x => compiled.IsMatch(((string)x.Key).Substring(plen)))
|
||||
.ToArray(); // evaluate while locked
|
||||
}
|
||||
finally
|
||||
{
|
||||
ExitReadLock();
|
||||
}
|
||||
return entries
|
||||
.Select(x => GetSafeLazyValue((Lazy<object>)x.Value)) // return exceptions as null
|
||||
.Where(x => x != null); // backward compat, don't store null values in the cache
|
||||
}
|
||||
|
||||
public virtual void ClearAllCache()
|
||||
/// <inheritdoc />
|
||||
public virtual void Clear()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -106,7 +102,8 @@ namespace Umbraco.Core.Cache
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void ClearCacheItem(string key)
|
||||
/// <inheritdoc />
|
||||
public virtual void Clear(string key)
|
||||
{
|
||||
var cacheKey = GetCacheKey(key);
|
||||
try
|
||||
@@ -120,7 +117,8 @@ namespace Umbraco.Core.Cache
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void ClearCacheObjectTypes(string typeName)
|
||||
/// <inheritdoc />
|
||||
public virtual void ClearOfType(string typeName)
|
||||
{
|
||||
var type = TypeFinder.GetTypeByName(typeName);
|
||||
if (type == null) return;
|
||||
@@ -149,7 +147,8 @@ namespace Umbraco.Core.Cache
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void ClearCacheObjectTypes<T>()
|
||||
/// <inheritdoc />
|
||||
public virtual void ClearOfType<T>()
|
||||
{
|
||||
var typeOfT = typeof(T);
|
||||
var isInterface = typeOfT.IsInterface;
|
||||
@@ -178,7 +177,8 @@ namespace Umbraco.Core.Cache
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void ClearCacheObjectTypes<T>(Func<string, T, bool> predicate)
|
||||
/// <inheritdoc />
|
||||
public virtual void ClearOfType<T>(Func<string, T, bool> predicate)
|
||||
{
|
||||
var typeOfT = typeof(T);
|
||||
var isInterface = typeOfT.IsInterface;
|
||||
@@ -210,7 +210,8 @@ namespace Umbraco.Core.Cache
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void ClearCacheByKeySearch(string keyStartsWith)
|
||||
/// <inheritdoc />
|
||||
public virtual void ClearByKey(string keyStartsWith)
|
||||
{
|
||||
var plen = CacheItemPrefix.Length + 1;
|
||||
try
|
||||
@@ -227,14 +228,16 @@ namespace Umbraco.Core.Cache
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void ClearCacheByKeyExpression(string regexString)
|
||||
/// <inheritdoc />
|
||||
public virtual void ClearByRegex(string regex)
|
||||
{
|
||||
var compiled = new Regex(regex, RegexOptions.Compiled);
|
||||
var plen = CacheItemPrefix.Length + 1;
|
||||
try
|
||||
{
|
||||
EnterWriteLock();
|
||||
foreach (var entry in GetDictionaryEntries()
|
||||
.Where(x => Regex.IsMatch(((string)x.Key).Substring(plen), regexString))
|
||||
.Where(x => compiled.IsMatch(((string)x.Key).Substring(plen)))
|
||||
.ToArray())
|
||||
RemoveEntry((string) entry.Key);
|
||||
}
|
||||
@@ -246,67 +249,80 @@ namespace Umbraco.Core.Cache
|
||||
|
||||
#endregion
|
||||
|
||||
#region Get
|
||||
#region Dictionary
|
||||
|
||||
public virtual IEnumerable<object> GetCacheItemsByKeySearch(string keyStartsWith)
|
||||
// manipulate the underlying cache entries
|
||||
// these *must* be called from within the appropriate locks
|
||||
// and use the full prefixed cache keys
|
||||
protected abstract IEnumerable<DictionaryEntry> GetDictionaryEntries();
|
||||
protected abstract void RemoveEntry(string key);
|
||||
protected abstract object GetEntry(string key);
|
||||
|
||||
// read-write lock the underlying cache
|
||||
//protected abstract IDisposable ReadLock { get; }
|
||||
//protected abstract IDisposable WriteLock { get; }
|
||||
|
||||
protected abstract void EnterReadLock();
|
||||
protected abstract void ExitReadLock();
|
||||
protected abstract void EnterWriteLock();
|
||||
protected abstract void ExitWriteLock();
|
||||
|
||||
protected string GetCacheKey(string key)
|
||||
{
|
||||
var plen = CacheItemPrefix.Length + 1;
|
||||
IEnumerable<DictionaryEntry> entries;
|
||||
try
|
||||
{
|
||||
EnterReadLock();
|
||||
entries = GetDictionaryEntries()
|
||||
.Where(x => ((string)x.Key).Substring(plen).InvariantStartsWith(keyStartsWith))
|
||||
.ToArray(); // evaluate while locked
|
||||
}
|
||||
finally
|
||||
{
|
||||
ExitReadLock();
|
||||
}
|
||||
|
||||
return entries
|
||||
.Select(x => GetSafeLazyValue((Lazy<object>)x.Value)) // return exceptions as null
|
||||
.Where(x => x != null); // backward compat, don't store null values in the cache
|
||||
return $"{CacheItemPrefix}-{key}";
|
||||
}
|
||||
|
||||
public virtual IEnumerable<object> GetCacheItemsByKeyExpression(string regexString)
|
||||
protected internal static Lazy<object> GetSafeLazy(Func<object> getCacheItem)
|
||||
{
|
||||
const string prefix = CacheItemPrefix + "-";
|
||||
var plen = prefix.Length;
|
||||
IEnumerable<DictionaryEntry> entries;
|
||||
try
|
||||
// try to generate the value and if it fails,
|
||||
// wrap in an ExceptionHolder - would be much simpler
|
||||
// to just use lazy.IsValueFaulted alas that field is
|
||||
// internal
|
||||
return new Lazy<object>(() =>
|
||||
{
|
||||
EnterReadLock();
|
||||
entries = GetDictionaryEntries()
|
||||
.Where(x => Regex.IsMatch(((string)x.Key).Substring(plen), regexString))
|
||||
.ToArray(); // evaluate while locked
|
||||
}
|
||||
finally
|
||||
{
|
||||
ExitReadLock();
|
||||
}
|
||||
return entries
|
||||
.Select(x => GetSafeLazyValue((Lazy<object>)x.Value)) // return exceptions as null
|
||||
.Where(x => x != null); // backward compat, don't store null values in the cache
|
||||
try
|
||||
{
|
||||
return getCacheItem();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return new ExceptionHolder(ExceptionDispatchInfo.Capture(e));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public virtual object GetCacheItem(string cacheKey)
|
||||
protected internal static object GetSafeLazyValue(Lazy<object> lazy, bool onlyIfValueIsCreated = false)
|
||||
{
|
||||
cacheKey = GetCacheKey(cacheKey);
|
||||
Lazy<object> result;
|
||||
// if onlyIfValueIsCreated, do not trigger value creation
|
||||
// must return something, though, to differentiate from null values
|
||||
if (onlyIfValueIsCreated && lazy.IsValueCreated == false) return ValueNotCreated;
|
||||
|
||||
// if execution has thrown then lazy.IsValueCreated is false
|
||||
// and lazy.IsValueFaulted is true (but internal) so we use our
|
||||
// own exception holder (see Lazy<T> source code) to return null
|
||||
if (lazy.Value is ExceptionHolder) return null;
|
||||
|
||||
// we have a value and execution has not thrown so returning
|
||||
// here does not throw - unless we're re-entering, take care of it
|
||||
try
|
||||
{
|
||||
EnterReadLock();
|
||||
result = GetEntry(cacheKey) as Lazy<object>; // null if key not found
|
||||
return lazy.Value;
|
||||
}
|
||||
finally
|
||||
catch (InvalidOperationException e)
|
||||
{
|
||||
ExitReadLock();
|
||||
throw new InvalidOperationException("The method that computes a value for the cache has tried to read that value from the cache.", e);
|
||||
}
|
||||
return result == null ? null : GetSafeLazyValue(result); // return exceptions as null
|
||||
}
|
||||
|
||||
public abstract object GetCacheItem(string cacheKey, Func<object> getCacheItem);
|
||||
internal class ExceptionHolder
|
||||
{
|
||||
public ExceptionHolder(ExceptionDispatchInfo e)
|
||||
{
|
||||
Exception = e;
|
||||
}
|
||||
|
||||
public ExceptionDispatchInfo Exception { get; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using Umbraco.Core.Composing;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// Implements a fast <see cref="IAppCache"/> on top of a concurrent dictionary.
|
||||
/// </summary>
|
||||
internal class FastDictionaryCacheProvider : IAppCache
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the internal items dictionary, for tests only!
|
||||
/// </summary>
|
||||
internal readonly ConcurrentDictionary<string, Lazy<object>> Items = new ConcurrentDictionary<string, Lazy<object>>();
|
||||
|
||||
/// <inheritdoc />
|
||||
public object Get(string cacheKey)
|
||||
{
|
||||
Items.TryGetValue(cacheKey, out var result); // else null
|
||||
return result == null ? null : FastDictionaryAppCacheBase.GetSafeLazyValue(result); // return exceptions as null
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public object Get(string cacheKey, Func<object> getCacheItem)
|
||||
{
|
||||
var result = Items.GetOrAdd(cacheKey, k => FastDictionaryAppCacheBase.GetSafeLazy(getCacheItem));
|
||||
|
||||
var value = result.Value; // will not throw (safe lazy)
|
||||
if (!(value is FastDictionaryAppCacheBase.ExceptionHolder eh))
|
||||
return value;
|
||||
|
||||
// and... it's in the cache anyway - so contrary to other cache providers,
|
||||
// which would trick with GetSafeLazyValue, we need to remove by ourselves,
|
||||
// in order NOT to cache exceptions
|
||||
|
||||
Items.TryRemove(cacheKey, out result);
|
||||
eh.Exception.Throw(); // throw once!
|
||||
return null; // never reached
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<object> SearchByKey(string keyStartsWith)
|
||||
{
|
||||
return Items
|
||||
.Where(kvp => kvp.Key.InvariantStartsWith(keyStartsWith))
|
||||
.Select(kvp => FastDictionaryAppCacheBase.GetSafeLazyValue(kvp.Value))
|
||||
.Where(x => x != null);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<object> SearchByRegex(string regex)
|
||||
{
|
||||
var compiled = new Regex(regex, RegexOptions.Compiled);
|
||||
return Items
|
||||
.Where(kvp => compiled.IsMatch(kvp.Key))
|
||||
.Select(kvp => FastDictionaryAppCacheBase.GetSafeLazyValue(kvp.Value))
|
||||
.Where(x => x != null);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Clear()
|
||||
{
|
||||
Items.Clear();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Clear(string key)
|
||||
{
|
||||
Items.TryRemove(key, out _);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void ClearOfType(string typeName)
|
||||
{
|
||||
var type = TypeFinder.GetTypeByName(typeName);
|
||||
if (type == null) return;
|
||||
var isInterface = type.IsInterface;
|
||||
|
||||
foreach (var kvp in Items
|
||||
.Where(x =>
|
||||
{
|
||||
// entry.Value is Lazy<object> and not null, its value may be null
|
||||
// remove null values as well, does not hurt
|
||||
// get non-created as NonCreatedValue & exceptions as null
|
||||
var value = FastDictionaryAppCacheBase.GetSafeLazyValue(x.Value, true);
|
||||
|
||||
// if T is an interface remove anything that implements that interface
|
||||
// otherwise remove exact types (not inherited types)
|
||||
return value == null || (isInterface ? (type.IsInstanceOfType(value)) : (value.GetType() == type));
|
||||
}))
|
||||
Items.TryRemove(kvp.Key, out _);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void ClearOfType<T>()
|
||||
{
|
||||
var typeOfT = typeof(T);
|
||||
var isInterface = typeOfT.IsInterface;
|
||||
|
||||
foreach (var kvp in Items
|
||||
.Where(x =>
|
||||
{
|
||||
// entry.Value is Lazy<object> and not null, its value may be null
|
||||
// remove null values as well, does not hurt
|
||||
// compare on exact type, don't use "is"
|
||||
// get non-created as NonCreatedValue & exceptions as null
|
||||
var value = FastDictionaryAppCacheBase.GetSafeLazyValue(x.Value, true);
|
||||
|
||||
// if T is an interface remove anything that implements that interface
|
||||
// otherwise remove exact types (not inherited types)
|
||||
return value == null || (isInterface ? (value is T) : (value.GetType() == typeOfT));
|
||||
}))
|
||||
Items.TryRemove(kvp.Key, out _);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void ClearOfType<T>(Func<string, T, bool> predicate)
|
||||
{
|
||||
var typeOfT = typeof(T);
|
||||
var isInterface = typeOfT.IsInterface;
|
||||
|
||||
foreach (var kvp in Items
|
||||
.Where(x =>
|
||||
{
|
||||
// entry.Value is Lazy<object> and not null, its value may be null
|
||||
// remove null values as well, does not hurt
|
||||
// compare on exact type, don't use "is"
|
||||
// get non-created as NonCreatedValue & exceptions as null
|
||||
var value = FastDictionaryAppCacheBase.GetSafeLazyValue(x.Value, true);
|
||||
if (value == null) return true;
|
||||
|
||||
// if T is an interface remove anything that implements that interface
|
||||
// otherwise remove exact types (not inherited types)
|
||||
return (isInterface ? (value is T) : (value.GetType() == typeOfT))
|
||||
// run predicate on the 'public key' part only, ie without prefix
|
||||
&& predicate(x.Key, (T)value);
|
||||
}))
|
||||
Items.TryRemove(kvp.Key, out _);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void ClearByKey(string keyStartsWith)
|
||||
{
|
||||
foreach (var ikvp in Items
|
||||
.Where(kvp => kvp.Key.InvariantStartsWith(keyStartsWith)))
|
||||
Items.TryRemove(ikvp.Key, out _);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void ClearByRegex(string regex)
|
||||
{
|
||||
var compiled = new Regex(regex, RegexOptions.Compiled);
|
||||
foreach (var ikvp in Items
|
||||
.Where(kvp => compiled.IsMatch(kvp.Key)))
|
||||
Items.TryRemove(ikvp.Key, out _);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,7 @@ namespace Umbraco.Core.Cache
|
||||
private readonly Func<TEntity, TId> _entityGetId;
|
||||
private readonly bool _expires;
|
||||
|
||||
public FullDataSetRepositoryCachePolicy(IRuntimeCacheProvider cache, IScopeAccessor scopeAccessor, Func<TEntity, TId> entityGetId, bool expires)
|
||||
public FullDataSetRepositoryCachePolicy(IAppPolicedCache cache, IScopeAccessor scopeAccessor, Func<TEntity, TId> entityGetId, bool expires)
|
||||
: base(cache, scopeAccessor)
|
||||
{
|
||||
_entityGetId = entityGetId;
|
||||
@@ -55,11 +55,11 @@ namespace Umbraco.Core.Cache
|
||||
|
||||
if (_expires)
|
||||
{
|
||||
Cache.InsertCacheItem(key, () => new DeepCloneableList<TEntity>(entities), TimeSpan.FromMinutes(5), true);
|
||||
Cache.Insert(key, () => new DeepCloneableList<TEntity>(entities), TimeSpan.FromMinutes(5), true);
|
||||
}
|
||||
else
|
||||
{
|
||||
Cache.InsertCacheItem(key, () => new DeepCloneableList<TEntity>(entities));
|
||||
Cache.Insert(key, () => new DeepCloneableList<TEntity>(entities));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,7 +171,7 @@ namespace Umbraco.Core.Cache
|
||||
/// <inheritdoc />
|
||||
public override void ClearAll()
|
||||
{
|
||||
Cache.ClearCacheItem(GetEntityTypeCacheKey());
|
||||
Cache.Clear(GetEntityTypeCacheKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+67
-90
@@ -7,54 +7,83 @@ using System.Web;
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// A cache provider that caches items in the HttpContext.Items
|
||||
/// Implements a fast <see cref="IAppCache"/> on top of HttpContext.Items.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If the Items collection is null, then this provider has no effect
|
||||
/// <para>If no current HttpContext items can be found (no current HttpContext,
|
||||
/// or no Items...) then this cache acts as a pass-through and does not cache
|
||||
/// anything.</para>
|
||||
/// </remarks>
|
||||
internal class HttpRequestCacheProvider : DictionaryCacheProviderBase
|
||||
internal class HttpRequestAppCache : FastDictionaryAppCacheBase
|
||||
{
|
||||
// context provider
|
||||
// the idea is that there is only one, application-wide HttpRequestCacheProvider instance,
|
||||
// that is initialized with a method that returns the "current" context.
|
||||
// NOTE
|
||||
// but then it is initialized with () => new HttpContextWrapper(HttpContent.Current)
|
||||
// which is higly inefficient because it creates a new wrapper each time we refer to _context()
|
||||
// so replace it with _context1 and _context2 below + a way to get context.Items.
|
||||
//private readonly Func<HttpContextBase> _context;
|
||||
|
||||
// NOTE
|
||||
// and then in almost 100% cases _context2 will be () => HttpContext.Current
|
||||
// so why not bring that logic in here and fallback on to HttpContext.Current when
|
||||
// _context1 is null?
|
||||
//private readonly HttpContextBase _context1;
|
||||
//private readonly Func<HttpContext> _context2;
|
||||
private readonly HttpContextBase _context;
|
||||
|
||||
private IDictionary ContextItems
|
||||
{
|
||||
//get { return _context1 != null ? _context1.Items : _context2().Items; }
|
||||
get { return _context != null ? _context.Items : HttpContext.Current.Items; }
|
||||
}
|
||||
|
||||
private bool HasContextItems
|
||||
{
|
||||
get { return (_context != null && _context.Items != null) || HttpContext.Current != null; }
|
||||
}
|
||||
|
||||
// for unit tests
|
||||
public HttpRequestCacheProvider(HttpContextBase context)
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="HttpRequestAppCache"/> class with a context, for unit tests!
|
||||
/// </summary>
|
||||
public HttpRequestAppCache(HttpContextBase context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
// main constructor
|
||||
// will use HttpContext.Current
|
||||
public HttpRequestCacheProvider(/*Func<HttpContext> context*/)
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="HttpRequestAppCache"/> class.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>Will use HttpContext.Current.</para>
|
||||
/// fixme - should use IHttpContextAccessor
|
||||
/// </remarks>
|
||||
public HttpRequestAppCache()
|
||||
{ }
|
||||
|
||||
private IDictionary ContextItems => _context?.Items ?? HttpContext.Current?.Items;
|
||||
|
||||
private bool HasContextItems => _context?.Items != null || HttpContext.Current != null;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override object Get(string key, Func<object> factory)
|
||||
{
|
||||
//_context2 = context;
|
||||
//no place to cache so just return the callback result
|
||||
if (HasContextItems == false) return factory();
|
||||
|
||||
key = GetCacheKey(key);
|
||||
|
||||
Lazy<object> result;
|
||||
|
||||
try
|
||||
{
|
||||
EnterWriteLock();
|
||||
result = ContextItems[key] as Lazy<object>; // null if key not found
|
||||
|
||||
// cannot create value within the lock, so if result.IsValueCreated is false, just
|
||||
// do nothing here - means that if creation throws, a race condition could cause
|
||||
// more than one thread to reach the return statement below and throw - accepted.
|
||||
|
||||
if (result == null || GetSafeLazyValue(result, true) == null) // get non-created as NonCreatedValue & exceptions as null
|
||||
{
|
||||
result = GetSafeLazy(factory);
|
||||
ContextItems[key] = result;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
ExitWriteLock();
|
||||
}
|
||||
|
||||
// using GetSafeLazy and GetSafeLazyValue ensures that we don't cache
|
||||
// exceptions (but try again and again) and silently eat them - however at
|
||||
// some point we have to report them - so need to re-throw here
|
||||
|
||||
// this does not throw anymore
|
||||
//return result.Value;
|
||||
|
||||
var value = result.Value; // will not throw (safe lazy)
|
||||
if (value is ExceptionHolder eh) eh.Exception.Throw(); // throw once!
|
||||
return value;
|
||||
}
|
||||
|
||||
#region Entries
|
||||
|
||||
protected override IEnumerable<DictionaryEntry> GetDictionaryEntries()
|
||||
{
|
||||
const string prefix = CacheItemPrefix + "-";
|
||||
@@ -62,7 +91,7 @@ namespace Umbraco.Core.Cache
|
||||
if (HasContextItems == false) return Enumerable.Empty<DictionaryEntry>();
|
||||
|
||||
return ContextItems.Cast<DictionaryEntry>()
|
||||
.Where(x => x.Key is string && ((string)x.Key).StartsWith(prefix));
|
||||
.Where(x => x.Key is string s && s.StartsWith(prefix));
|
||||
}
|
||||
|
||||
protected override void RemoveEntry(string key)
|
||||
@@ -77,6 +106,8 @@ namespace Umbraco.Core.Cache
|
||||
return HasContextItems ? ContextItems[key] : null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Lock
|
||||
|
||||
private bool _entered;
|
||||
@@ -103,59 +134,5 @@ namespace Umbraco.Core.Cache
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Get
|
||||
|
||||
public override object GetCacheItem(string cacheKey, Func<object> getCacheItem)
|
||||
{
|
||||
//no place to cache so just return the callback result
|
||||
if (HasContextItems == false) return getCacheItem();
|
||||
|
||||
cacheKey = GetCacheKey(cacheKey);
|
||||
|
||||
Lazy<object> result;
|
||||
|
||||
try
|
||||
{
|
||||
EnterWriteLock();
|
||||
result = ContextItems[cacheKey] as Lazy<object>; // null if key not found
|
||||
|
||||
// cannot create value within the lock, so if result.IsValueCreated is false, just
|
||||
// do nothing here - means that if creation throws, a race condition could cause
|
||||
// more than one thread to reach the return statement below and throw - accepted.
|
||||
|
||||
if (result == null || GetSafeLazyValue(result, true) == null) // get non-created as NonCreatedValue & exceptions as null
|
||||
{
|
||||
result = GetSafeLazy(getCacheItem);
|
||||
ContextItems[cacheKey] = result;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
ExitWriteLock();
|
||||
}
|
||||
|
||||
// using GetSafeLazy and GetSafeLazyValue ensures that we don't cache
|
||||
// exceptions (but try again and again) and silently eat them - however at
|
||||
// some point we have to report them - so need to re-throw here
|
||||
|
||||
// this does not throw anymore
|
||||
//return result.Value;
|
||||
|
||||
var value = result.Value; // will not throw (safe lazy)
|
||||
if (value is ExceptionHolder eh) eh.Exception.Throw(); // throw once!
|
||||
return value;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Insert
|
||||
#endregion
|
||||
|
||||
private class NoopLocker : DisposableObjectSlim
|
||||
{
|
||||
protected override void DisposeResources()
|
||||
{ }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines an application cache.
|
||||
/// </summary>
|
||||
public interface IAppCache
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets an item identified by its key.
|
||||
/// </summary>
|
||||
/// <param name="key">The key of the item.</param>
|
||||
/// <returns>The item, or null if the item was not found.</returns>
|
||||
object Get(string key);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or creates an item identified by its key.
|
||||
/// </summary>
|
||||
/// <param name="key">The key of the item.</param>
|
||||
/// <param name="factory">A factory function that can create the item.</param>
|
||||
/// <returns>The item.</returns>
|
||||
object Get(string key, Func<object> factory);
|
||||
|
||||
/// <summary>
|
||||
/// Gets items with a key starting with the specified value.
|
||||
/// </summary>
|
||||
/// <param name="keyStartsWith">The StartsWith value to use in the search.</param>
|
||||
/// <returns>Items matching the search.</returns>
|
||||
IEnumerable<object> SearchByKey(string keyStartsWith);
|
||||
|
||||
/// <summary>
|
||||
/// Gets items with a key matching a regular expression.
|
||||
/// </summary>
|
||||
/// <param name="regex">The regular expression.</param>
|
||||
/// <returns>Items matching the search.</returns>
|
||||
IEnumerable<object> SearchByRegex(string regex);
|
||||
|
||||
/// <summary>
|
||||
/// Removes all items from the cache.
|
||||
/// </summary>
|
||||
void Clear();
|
||||
|
||||
/// <summary>
|
||||
/// Removes an item identified by its key from the cache.
|
||||
/// </summary>
|
||||
/// <param name="key">The key of the item.</param>
|
||||
void Clear(string key);
|
||||
|
||||
/// <summary>
|
||||
/// Removes items of a specified type from the cache.
|
||||
/// </summary>
|
||||
/// <param name="typeName">The name of the type to remove.</param>
|
||||
/// <remarks>
|
||||
/// <para>If the type is an interface, then all items of a type implementing that interface are
|
||||
/// removed. Otherwise, only items of that exact type are removed (items of type inheriting from
|
||||
/// the specified type are not removed).</para>
|
||||
/// <para>Performs a case-sensitive search.</para>
|
||||
/// </remarks>
|
||||
void ClearOfType(string typeName);
|
||||
|
||||
/// <summary>
|
||||
/// Removes items of a specified type from the cache.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the items to remove.</typeparam>
|
||||
/// <remarks>If the type is an interface, then all items of a type implementing that interface are
|
||||
/// removed. Otherwise, only items of that exact type are removed (items of type inheriting from
|
||||
/// the specified type are not removed).</remarks>
|
||||
void ClearOfType<T>();
|
||||
|
||||
/// <summary>
|
||||
/// Removes items of a specified type from the cache.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the items to remove.</typeparam>
|
||||
/// <param name="predicate">The predicate to satisfy.</param>
|
||||
/// <remarks>If the type is an interface, then all items of a type implementing that interface are
|
||||
/// removed. Otherwise, only items of that exact type are removed (items of type inheriting from
|
||||
/// the specified type are not removed).</remarks>
|
||||
void ClearOfType<T>(Func<string, T, bool> predicate);
|
||||
|
||||
/// <summary>
|
||||
/// Clears items with a key starting with the specified value.
|
||||
/// </summary>
|
||||
/// <param name="keyStartsWith">The StartsWith value to use in the search.</param>
|
||||
void ClearByKey(string keyStartsWith);
|
||||
|
||||
/// <summary>
|
||||
/// Clears items with a key matching a regular expression.
|
||||
/// </summary>
|
||||
/// <param name="regex">The regular expression.</param>
|
||||
void ClearByRegex(string regex);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
using System;
|
||||
using System.Web.Caching;
|
||||
|
||||
// fixme should this be/support non-web?
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines an application cache that support cache policies.
|
||||
/// </summary>
|
||||
/// <remarks>A cache policy can be used to cache with timeouts,
|
||||
/// or depending on files, and with a remove callback, etc.</remarks>
|
||||
public interface IAppPolicedCache : IAppCache
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets an item identified by its key.
|
||||
/// </summary>
|
||||
/// <param name="key">The key of the item.</param>
|
||||
/// <param name="factory">A factory function that can create the item.</param>
|
||||
/// <param name="timeout">An optional cache timeout.</param>
|
||||
/// <param name="isSliding">An optional value indicating whether the cache timeout is sliding (default is false).</param>
|
||||
/// <param name="priority">An optional cache priority (default is Normal).</param>
|
||||
/// <param name="removedCallback">An optional callback to handle removals.</param>
|
||||
/// <param name="dependentFiles">Files the cache entry depends on.</param>
|
||||
/// <returns>The item.</returns>
|
||||
object Get(
|
||||
string key,
|
||||
Func<object> factory,
|
||||
TimeSpan? timeout,
|
||||
bool isSliding = false,
|
||||
CacheItemPriority priority = CacheItemPriority.Normal,
|
||||
CacheItemRemovedCallback removedCallback = null,
|
||||
string[] dependentFiles = null);
|
||||
|
||||
/// <summary>
|
||||
/// Inserts an item.
|
||||
/// </summary>
|
||||
/// <param name="key">The key of the item.</param>
|
||||
/// <param name="factory">A factory function that can create the item.</param>
|
||||
/// <param name="timeout">An optional cache timeout.</param>
|
||||
/// <param name="isSliding">An optional value indicating whether the cache timeout is sliding (default is false).</param>
|
||||
/// <param name="priority">An optional cache priority (default is Normal).</param>
|
||||
/// <param name="removedCallback">An optional callback to handle removals.</param>
|
||||
/// <param name="dependentFiles">Files the cache entry depends on.</param>
|
||||
void Insert(
|
||||
string key,
|
||||
Func<object> factory,
|
||||
TimeSpan? timeout = null,
|
||||
bool isSliding = false,
|
||||
CacheItemPriority priority = CacheItemPriority.Normal,
|
||||
CacheItemRemovedCallback removedCallback = null,
|
||||
string[] dependentFiles = null);
|
||||
}
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// An interface for implementing a basic cache provider
|
||||
/// </summary>
|
||||
public interface ICacheProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Removes all items from the cache.
|
||||
/// </summary>
|
||||
void ClearAllCache();
|
||||
|
||||
/// <summary>
|
||||
/// Removes an item from the cache, identified by its key.
|
||||
/// </summary>
|
||||
/// <param name="key">The key of the item.</param>
|
||||
void ClearCacheItem(string key);
|
||||
|
||||
/// <summary>
|
||||
/// Removes items from the cache, of a specified type.
|
||||
/// </summary>
|
||||
/// <param name="typeName">The name of the type to remove.</param>
|
||||
/// <remarks>
|
||||
/// <para>If the type is an interface, then all items of a type implementing that interface are
|
||||
/// removed. Otherwise, only items of that exact type are removed (items of type inheriting from
|
||||
/// the specified type are not removed).</para>
|
||||
/// <para>Performs a case-sensitive search.</para>
|
||||
/// </remarks>
|
||||
void ClearCacheObjectTypes(string typeName);
|
||||
|
||||
/// <summary>
|
||||
/// Removes items from the cache, of a specified type.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the items to remove.</typeparam>
|
||||
/// <remarks>If the type is an interface, then all items of a type implementing that interface are
|
||||
/// removed. Otherwise, only items of that exact type are removed (items of type inheriting from
|
||||
/// the specified type are not removed).</remarks>
|
||||
void ClearCacheObjectTypes<T>();
|
||||
|
||||
/// <summary>
|
||||
/// Removes items from the cache, of a specified type, satisfying a predicate.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the items to remove.</typeparam>
|
||||
/// <param name="predicate">The predicate to satisfy.</param>
|
||||
/// <remarks>If the type is an interface, then all items of a type implementing that interface are
|
||||
/// removed. Otherwise, only items of that exact type are removed (items of type inheriting from
|
||||
/// the specified type are not removed).</remarks>
|
||||
void ClearCacheObjectTypes<T>(Func<string, T, bool> predicate);
|
||||
|
||||
void ClearCacheByKeySearch(string keyStartsWith);
|
||||
void ClearCacheByKeyExpression(string regexString);
|
||||
|
||||
IEnumerable<object> GetCacheItemsByKeySearch(string keyStartsWith);
|
||||
IEnumerable<object> GetCacheItemsByKeyExpression(string regexString);
|
||||
|
||||
/// <summary>
|
||||
/// Returns an item with a given key
|
||||
/// </summary>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <returns></returns>
|
||||
object GetCacheItem(string cacheKey);
|
||||
|
||||
object GetCacheItem(string cacheKey, Func<object> getCacheItem);
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
using System;
|
||||
using System.Runtime.Caching;
|
||||
using System.Text;
|
||||
using System.Web.Caching;
|
||||
using CacheItemPriority = System.Web.Caching.CacheItemPriority;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// An abstract class for implementing a runtime cache provider
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// </remarks>
|
||||
public interface IRuntimeCacheProvider : ICacheProvider
|
||||
{
|
||||
object GetCacheItem(
|
||||
string cacheKey,
|
||||
Func<object> getCacheItem,
|
||||
TimeSpan? timeout,
|
||||
bool isSliding = false,
|
||||
CacheItemPriority priority = CacheItemPriority.Normal,
|
||||
CacheItemRemovedCallback removedCallback = null,
|
||||
string[] dependentFiles = null);
|
||||
|
||||
void InsertCacheItem(
|
||||
string cacheKey,
|
||||
Func<object> getCacheItem,
|
||||
TimeSpan? timeout = null,
|
||||
bool isSliding = false,
|
||||
CacheItemPriority priority = CacheItemPriority.Normal,
|
||||
CacheItemRemovedCallback removedCallback = null,
|
||||
string[] dependentFiles = null);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a dictionary of <see cref="IAppPolicedCache"/> for types.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>Isolated caches are used by e.g. repositories, to ensure that each cached entity
|
||||
/// type has its own cache, so that lookups are fast and the repository does not need to
|
||||
/// search through all keys on a global scale.</para>
|
||||
/// </remarks>
|
||||
public class IsolatedCaches : AppPolicedCacheDictionary<Type>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="IsolatedCaches"/> class.
|
||||
/// </summary>
|
||||
/// <param name="cacheFactory"></param>
|
||||
public IsolatedCaches(Func<Type, IAppPolicedCache> cacheFactory)
|
||||
: base(cacheFactory)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a cache.
|
||||
/// </summary>
|
||||
public IAppPolicedCache GetOrCreate<T>()
|
||||
=> GetOrCreate(typeof(T));
|
||||
|
||||
/// <summary>
|
||||
/// Tries to get a cache.
|
||||
/// </summary>
|
||||
public Attempt<IAppPolicedCache> Get<T>()
|
||||
=> Get(typeof(T));
|
||||
|
||||
/// <summary>
|
||||
/// Clears a cache.
|
||||
/// </summary>
|
||||
public void ClearCache<T>()
|
||||
=> ClearCache(typeof(T));
|
||||
}
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to get/create/manipulate isolated runtime cache
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is useful for repository level caches to ensure that cache lookups by key are fast so
|
||||
/// that the repository doesn't need to search through all keys on a global scale.
|
||||
/// </remarks>
|
||||
public class IsolatedRuntimeCache
|
||||
{
|
||||
internal Func<Type, IRuntimeCacheProvider> CacheFactory { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Constructor that allows specifying a factory for the type of runtime isolated cache to create
|
||||
/// </summary>
|
||||
/// <param name="cacheFactory"></param>
|
||||
public IsolatedRuntimeCache(Func<Type, IRuntimeCacheProvider> cacheFactory)
|
||||
{
|
||||
CacheFactory = cacheFactory;
|
||||
}
|
||||
|
||||
private readonly ConcurrentDictionary<Type, IRuntimeCacheProvider> _isolatedCache = new ConcurrentDictionary<Type, IRuntimeCacheProvider>();
|
||||
|
||||
/// <summary>
|
||||
/// Returns an isolated runtime cache for a given type
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public IRuntimeCacheProvider GetOrCreateCache<T>()
|
||||
{
|
||||
return _isolatedCache.GetOrAdd(typeof(T), type => CacheFactory(type));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an isolated runtime cache for a given type
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IRuntimeCacheProvider GetOrCreateCache(Type type)
|
||||
{
|
||||
return _isolatedCache.GetOrAdd(type, t => CacheFactory(t));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to get a cache by the type specified
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public Attempt<IRuntimeCacheProvider> GetCache<T>()
|
||||
{
|
||||
IRuntimeCacheProvider cache;
|
||||
if (_isolatedCache.TryGetValue(typeof(T), out cache))
|
||||
{
|
||||
return Attempt.Succeed(cache);
|
||||
}
|
||||
return Attempt<IRuntimeCacheProvider>.Fail();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears all values inside this isolated runtime cache
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public void ClearCache<T>()
|
||||
{
|
||||
IRuntimeCacheProvider cache;
|
||||
if (_isolatedCache.TryGetValue(typeof(T), out cache))
|
||||
{
|
||||
cache.ClearAllCache();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears all of the isolated caches
|
||||
/// </summary>
|
||||
public void ClearAllCaches()
|
||||
{
|
||||
foreach (var key in _isolatedCache.Keys)
|
||||
{
|
||||
IRuntimeCacheProvider cache;
|
||||
if (_isolatedCache.TryRemove(key, out cache))
|
||||
{
|
||||
cache.ClearAllCache();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web.Caching;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// Implements <see cref="IAppPolicedCache"/> and do not cache.
|
||||
/// </summary>
|
||||
public class NoAppCache : IAppPolicedCache
|
||||
{
|
||||
private NoAppCache() { }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the singleton instance.
|
||||
/// </summary>
|
||||
public static NoAppCache Instance { get; } = new NoAppCache();
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual object Get(string cacheKey)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual object Get(string cacheKey, Func<object> factory)
|
||||
{
|
||||
return factory();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual IEnumerable<object> SearchByKey(string keyStartsWith)
|
||||
{
|
||||
return Enumerable.Empty<object>();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<object> SearchByRegex(string regex)
|
||||
{
|
||||
return Enumerable.Empty<object>();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public object Get(string key, Func<object> factory, TimeSpan? timeout, bool isSliding = false, CacheItemPriority priority = CacheItemPriority.Normal, CacheItemRemovedCallback removedCallback = null, string[] dependentFiles = null)
|
||||
{
|
||||
return factory();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Insert(string key, Func<object> factory, TimeSpan? timeout = null, bool isSliding = false, CacheItemPriority priority = CacheItemPriority.Normal, CacheItemRemovedCallback removedCallback = null, string[] dependentFiles = null)
|
||||
{ }
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual void Clear()
|
||||
{ }
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual void Clear(string key)
|
||||
{ }
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual void ClearOfType(string typeName)
|
||||
{ }
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual void ClearOfType<T>()
|
||||
{ }
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual void ClearOfType<T>(Func<string, T, bool> predicate)
|
||||
{ }
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual void ClearByKey(string keyStartsWith)
|
||||
{ }
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual void ClearByRegex(string regex)
|
||||
{ }
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@ namespace Umbraco.Core.Cache
|
||||
|
||||
public static NoCacheRepositoryCachePolicy<TEntity, TId> Instance { get; } = new NoCacheRepositoryCachePolicy<TEntity, TId>();
|
||||
|
||||
public IRepositoryCachePolicy<TEntity, TId> Scoped(IRuntimeCacheProvider runtimeCache, IScope scope)
|
||||
public IRepositoryCachePolicy<TEntity, TId> Scoped(IAppPolicedCache runtimeCache, IScope scope)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web.Caching;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a cache provider that does not cache anything.
|
||||
/// </summary>
|
||||
public class NullCacheProvider : IRuntimeCacheProvider
|
||||
{
|
||||
private NullCacheProvider() { }
|
||||
|
||||
public static NullCacheProvider Instance { get; } = new NullCacheProvider();
|
||||
|
||||
public virtual void ClearAllCache()
|
||||
{ }
|
||||
|
||||
public virtual void ClearCacheItem(string key)
|
||||
{ }
|
||||
|
||||
public virtual void ClearCacheObjectTypes(string typeName)
|
||||
{ }
|
||||
|
||||
public virtual void ClearCacheObjectTypes<T>()
|
||||
{ }
|
||||
|
||||
public virtual void ClearCacheObjectTypes<T>(Func<string, T, bool> predicate)
|
||||
{ }
|
||||
|
||||
public virtual void ClearCacheByKeySearch(string keyStartsWith)
|
||||
{ }
|
||||
|
||||
public virtual void ClearCacheByKeyExpression(string regexString)
|
||||
{ }
|
||||
|
||||
public virtual IEnumerable<object> GetCacheItemsByKeySearch(string keyStartsWith)
|
||||
{
|
||||
return Enumerable.Empty<object>();
|
||||
}
|
||||
|
||||
public IEnumerable<object> GetCacheItemsByKeyExpression(string regexString)
|
||||
{
|
||||
return Enumerable.Empty<object>();
|
||||
}
|
||||
|
||||
public virtual object GetCacheItem(string cacheKey)
|
||||
{
|
||||
return default(object);
|
||||
}
|
||||
|
||||
public virtual object GetCacheItem(string cacheKey, Func<object> getCacheItem)
|
||||
{
|
||||
return getCacheItem();
|
||||
}
|
||||
|
||||
public object GetCacheItem(string cacheKey, Func<object> getCacheItem, TimeSpan? timeout, bool isSliding = false, CacheItemPriority priority = CacheItemPriority.Normal, CacheItemRemovedCallback removedCallback = null, string[] dependentFiles = null)
|
||||
{
|
||||
return getCacheItem();
|
||||
}
|
||||
|
||||
public void InsertCacheItem(string cacheKey, Func<object> getCacheItem, TimeSpan? timeout = null, bool isSliding = false, CacheItemPriority priority = CacheItemPriority.Normal, CacheItemRemovedCallback removedCallback = null, string[] dependentFiles = null)
|
||||
{ }
|
||||
}
|
||||
}
|
||||
+144
-139
@@ -11,31 +11,142 @@ using CacheItemPriority = System.Web.Caching.CacheItemPriority;
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a cache provider that caches item in a <see cref="MemoryCache"/>.
|
||||
/// A cache provider that wraps the logic of a System.Runtime.Caching.ObjectCache
|
||||
/// Implements <see cref="IAppPolicedCache"/> on top of a <see cref="ObjectCache"/>.
|
||||
/// </summary>
|
||||
/// <remarks>The <see cref="MemoryCache"/> is created with name "in-memory". That name is
|
||||
/// used to retrieve configuration options. It does not identify the memory cache, i.e.
|
||||
/// each instance of this class has its own, independent, memory cache.</remarks>
|
||||
public class ObjectCacheRuntimeCacheProvider : IRuntimeCacheProvider
|
||||
public class ObjectCacheAppCache : IAppPolicedCache
|
||||
{
|
||||
private readonly ReaderWriterLockSlim _locker = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
|
||||
internal ObjectCache MemoryCache;
|
||||
|
||||
/// <summary>
|
||||
/// Used for debugging
|
||||
/// Initializes a new instance of the <see cref="ObjectCacheAppCache"/>.
|
||||
/// </summary>
|
||||
internal Guid InstanceId { get; private set; }
|
||||
|
||||
public ObjectCacheRuntimeCacheProvider()
|
||||
public ObjectCacheAppCache()
|
||||
{
|
||||
// the MemoryCache is created with name "in-memory". That name is
|
||||
// used to retrieve configuration options. It does not identify the memory cache, i.e.
|
||||
// each instance of this class has its own, independent, memory cache.
|
||||
MemoryCache = new MemoryCache("in-memory");
|
||||
InstanceId = Guid.NewGuid();
|
||||
}
|
||||
|
||||
#region Clear
|
||||
/// <summary>
|
||||
/// Gets the internal memory cache, for tests only!
|
||||
/// </summary>
|
||||
internal readonly ObjectCache MemoryCache;
|
||||
|
||||
public virtual void ClearAllCache()
|
||||
/// <inheritdoc />
|
||||
public object Get(string key)
|
||||
{
|
||||
Lazy<object> result;
|
||||
try
|
||||
{
|
||||
_locker.EnterReadLock();
|
||||
result = MemoryCache.Get(key) as Lazy<object>; // null if key not found
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (_locker.IsReadLockHeld)
|
||||
_locker.ExitReadLock();
|
||||
}
|
||||
return result == null ? null : FastDictionaryAppCacheBase.GetSafeLazyValue(result); // return exceptions as null
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public object Get(string key, Func<object> factory)
|
||||
{
|
||||
return Get(key, factory, null);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<object> SearchByKey(string keyStartsWith)
|
||||
{
|
||||
KeyValuePair<string, object>[] entries;
|
||||
try
|
||||
{
|
||||
_locker.EnterReadLock();
|
||||
entries = MemoryCache
|
||||
.Where(x => x.Key.InvariantStartsWith(keyStartsWith))
|
||||
.ToArray(); // evaluate while locked
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (_locker.IsReadLockHeld)
|
||||
_locker.ExitReadLock();
|
||||
}
|
||||
return entries
|
||||
.Select(x => FastDictionaryAppCacheBase.GetSafeLazyValue((Lazy<object>)x.Value)) // return exceptions as null
|
||||
.Where(x => x != null) // backward compat, don't store null values in the cache
|
||||
.ToList();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<object> SearchByRegex(string regex)
|
||||
{
|
||||
var compiled = new Regex(regex, RegexOptions.Compiled);
|
||||
|
||||
KeyValuePair<string, object>[] entries;
|
||||
try
|
||||
{
|
||||
_locker.EnterReadLock();
|
||||
entries = MemoryCache
|
||||
.Where(x => compiled.IsMatch(x.Key))
|
||||
.ToArray(); // evaluate while locked
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (_locker.IsReadLockHeld)
|
||||
_locker.ExitReadLock();
|
||||
}
|
||||
return entries
|
||||
.Select(x => FastDictionaryAppCacheBase.GetSafeLazyValue((Lazy<object>)x.Value)) // return exceptions as null
|
||||
.Where(x => x != null) // backward compat, don't store null values in the cache
|
||||
.ToList();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public object Get(string key, Func<object> factory, TimeSpan? timeout, bool isSliding = false, CacheItemPriority priority = CacheItemPriority.Normal, CacheItemRemovedCallback removedCallback = null, string[] dependentFiles = null)
|
||||
{
|
||||
// see notes in HttpRuntimeCacheProvider
|
||||
|
||||
Lazy<object> result;
|
||||
|
||||
using (var lck = new UpgradeableReadLock(_locker))
|
||||
{
|
||||
result = MemoryCache.Get(key) as Lazy<object>;
|
||||
if (result == null || FastDictionaryAppCacheBase.GetSafeLazyValue(result, true) == null) // get non-created as NonCreatedValue & exceptions as null
|
||||
{
|
||||
result = FastDictionaryAppCacheBase.GetSafeLazy(factory);
|
||||
var policy = GetPolicy(timeout, isSliding, removedCallback, dependentFiles);
|
||||
|
||||
lck.UpgradeToWriteLock();
|
||||
//NOTE: This does an add or update
|
||||
MemoryCache.Set(key, result, policy);
|
||||
}
|
||||
}
|
||||
|
||||
//return result.Value;
|
||||
|
||||
var value = result.Value; // will not throw (safe lazy)
|
||||
if (value is FastDictionaryAppCacheBase.ExceptionHolder eh) eh.Exception.Throw(); // throw once!
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Insert(string key, Func<object> factory, TimeSpan? timeout = null, bool isSliding = false, CacheItemPriority priority = CacheItemPriority.Normal, CacheItemRemovedCallback removedCallback = null, string[] dependentFiles = null)
|
||||
{
|
||||
// NOTE - here also we must insert a Lazy<object> but we can evaluate it right now
|
||||
// and make sure we don't store a null value.
|
||||
|
||||
var result = FastDictionaryAppCacheBase.GetSafeLazy(factory);
|
||||
var value = result.Value; // force evaluation now
|
||||
if (value == null) return; // do not store null values (backward compat)
|
||||
|
||||
var policy = GetPolicy(timeout, isSliding, removedCallback, dependentFiles);
|
||||
//NOTE: This does an add or update
|
||||
MemoryCache.Set(key, result, policy);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual void Clear()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -50,7 +161,8 @@ namespace Umbraco.Core.Cache
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void ClearCacheItem(string key)
|
||||
/// <inheritdoc />
|
||||
public virtual void Clear(string key)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -65,7 +177,8 @@ namespace Umbraco.Core.Cache
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void ClearCacheObjectTypes(string typeName)
|
||||
/// <inheritdoc />
|
||||
public virtual void ClearOfType(string typeName)
|
||||
{
|
||||
var type = TypeFinder.GetTypeByName(typeName);
|
||||
if (type == null) return;
|
||||
@@ -79,7 +192,7 @@ namespace Umbraco.Core.Cache
|
||||
// x.Value is Lazy<object> and not null, its value may be null
|
||||
// remove null values as well, does not hurt
|
||||
// get non-created as NonCreatedValue & exceptions as null
|
||||
var value = DictionaryCacheProviderBase.GetSafeLazyValue((Lazy<object>)x.Value, true);
|
||||
var value = FastDictionaryAppCacheBase.GetSafeLazyValue((Lazy<object>)x.Value, true);
|
||||
|
||||
// if T is an interface remove anything that implements that interface
|
||||
// otherwise remove exact types (not inherited types)
|
||||
@@ -96,12 +209,13 @@ namespace Umbraco.Core.Cache
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void ClearCacheObjectTypes<T>()
|
||||
/// <inheritdoc />
|
||||
public virtual void ClearOfType<T>()
|
||||
{
|
||||
try
|
||||
{
|
||||
_locker.EnterWriteLock();
|
||||
var typeOfT = typeof (T);
|
||||
var typeOfT = typeof(T);
|
||||
var isInterface = typeOfT.IsInterface;
|
||||
foreach (var key in MemoryCache
|
||||
.Where(x =>
|
||||
@@ -109,7 +223,7 @@ namespace Umbraco.Core.Cache
|
||||
// x.Value is Lazy<object> and not null, its value may be null
|
||||
// remove null values as well, does not hurt
|
||||
// get non-created as NonCreatedValue & exceptions as null
|
||||
var value = DictionaryCacheProviderBase.GetSafeLazyValue((Lazy<object>)x.Value, true);
|
||||
var value = FastDictionaryAppCacheBase.GetSafeLazyValue((Lazy<object>)x.Value, true);
|
||||
|
||||
// if T is an interface remove anything that implements that interface
|
||||
// otherwise remove exact types (not inherited types)
|
||||
@@ -127,7 +241,8 @@ namespace Umbraco.Core.Cache
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void ClearCacheObjectTypes<T>(Func<string, T, bool> predicate)
|
||||
/// <inheritdoc />
|
||||
public virtual void ClearOfType<T>(Func<string, T, bool> predicate)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -140,7 +255,7 @@ namespace Umbraco.Core.Cache
|
||||
// x.Value is Lazy<object> and not null, its value may be null
|
||||
// remove null values as well, does not hurt
|
||||
// get non-created as NonCreatedValue & exceptions as null
|
||||
var value = DictionaryCacheProviderBase.GetSafeLazyValue((Lazy<object>)x.Value, true);
|
||||
var value = FastDictionaryAppCacheBase.GetSafeLazyValue((Lazy<object>)x.Value, true);
|
||||
if (value == null) return true;
|
||||
|
||||
// if T is an interface remove anything that implements that interface
|
||||
@@ -159,7 +274,8 @@ namespace Umbraco.Core.Cache
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void ClearCacheByKeySearch(string keyStartsWith)
|
||||
/// <inheritdoc />
|
||||
public virtual void ClearByKey(string keyStartsWith)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -177,13 +293,16 @@ namespace Umbraco.Core.Cache
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void ClearCacheByKeyExpression(string regexString)
|
||||
/// <inheritdoc />
|
||||
public virtual void ClearByRegex(string regex)
|
||||
{
|
||||
var compiled = new Regex(regex, RegexOptions.Compiled);
|
||||
|
||||
try
|
||||
{
|
||||
_locker.EnterWriteLock();
|
||||
foreach (var key in MemoryCache
|
||||
.Where(x => Regex.IsMatch(x.Key, regexString))
|
||||
.Where(x => compiled.IsMatch(x.Key))
|
||||
.Select(x => x.Key)
|
||||
.ToArray()) // ToArray required to remove
|
||||
MemoryCache.Remove(key);
|
||||
@@ -195,120 +314,6 @@ namespace Umbraco.Core.Cache
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Get
|
||||
|
||||
public IEnumerable<object> GetCacheItemsByKeySearch(string keyStartsWith)
|
||||
{
|
||||
KeyValuePair<string, object>[] entries;
|
||||
try
|
||||
{
|
||||
_locker.EnterReadLock();
|
||||
entries = MemoryCache
|
||||
.Where(x => x.Key.InvariantStartsWith(keyStartsWith))
|
||||
.ToArray(); // evaluate while locked
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (_locker.IsReadLockHeld)
|
||||
_locker.ExitReadLock();
|
||||
}
|
||||
return entries
|
||||
.Select(x => DictionaryCacheProviderBase.GetSafeLazyValue((Lazy<object>)x.Value)) // return exceptions as null
|
||||
.Where(x => x != null) // backward compat, don't store null values in the cache
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public IEnumerable<object> GetCacheItemsByKeyExpression(string regexString)
|
||||
{
|
||||
KeyValuePair<string, object>[] entries;
|
||||
try
|
||||
{
|
||||
_locker.EnterReadLock();
|
||||
entries = MemoryCache
|
||||
.Where(x => Regex.IsMatch(x.Key, regexString))
|
||||
.ToArray(); // evaluate while locked
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (_locker.IsReadLockHeld)
|
||||
_locker.ExitReadLock();
|
||||
}
|
||||
return entries
|
||||
.Select(x => DictionaryCacheProviderBase.GetSafeLazyValue((Lazy<object>)x.Value)) // return exceptions as null
|
||||
.Where(x => x != null) // backward compat, don't store null values in the cache
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public object GetCacheItem(string cacheKey)
|
||||
{
|
||||
Lazy<object> result;
|
||||
try
|
||||
{
|
||||
_locker.EnterReadLock();
|
||||
result = MemoryCache.Get(cacheKey) as Lazy<object>; // null if key not found
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (_locker.IsReadLockHeld)
|
||||
_locker.ExitReadLock();
|
||||
}
|
||||
return result == null ? null : DictionaryCacheProviderBase.GetSafeLazyValue(result); // return exceptions as null
|
||||
}
|
||||
|
||||
public object GetCacheItem(string cacheKey, Func<object> getCacheItem)
|
||||
{
|
||||
return GetCacheItem(cacheKey, getCacheItem, null);
|
||||
}
|
||||
|
||||
public object GetCacheItem(string cacheKey, Func<object> getCacheItem, TimeSpan? timeout, bool isSliding = false, CacheItemPriority priority = CacheItemPriority.Normal, CacheItemRemovedCallback removedCallback = null, string[] dependentFiles = null)
|
||||
{
|
||||
// see notes in HttpRuntimeCacheProvider
|
||||
|
||||
Lazy<object> result;
|
||||
|
||||
using (var lck = new UpgradeableReadLock(_locker))
|
||||
{
|
||||
result = MemoryCache.Get(cacheKey) as Lazy<object>;
|
||||
if (result == null || DictionaryCacheProviderBase.GetSafeLazyValue(result, true) == null) // get non-created as NonCreatedValue & exceptions as null
|
||||
{
|
||||
result = DictionaryCacheProviderBase.GetSafeLazy(getCacheItem);
|
||||
var policy = GetPolicy(timeout, isSliding, removedCallback, dependentFiles);
|
||||
|
||||
lck.UpgradeToWriteLock();
|
||||
//NOTE: This does an add or update
|
||||
MemoryCache.Set(cacheKey, result, policy);
|
||||
}
|
||||
}
|
||||
|
||||
//return result.Value;
|
||||
|
||||
var value = result.Value; // will not throw (safe lazy)
|
||||
if (value is DictionaryCacheProviderBase.ExceptionHolder eh) eh.Exception.Throw(); // throw once!
|
||||
return value;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Insert
|
||||
|
||||
public void InsertCacheItem(string cacheKey, Func<object> getCacheItem, TimeSpan? timeout = null, bool isSliding = false, CacheItemPriority priority = CacheItemPriority.Normal, CacheItemRemovedCallback removedCallback = null, string[] dependentFiles = null)
|
||||
{
|
||||
// NOTE - here also we must insert a Lazy<object> but we can evaluate it right now
|
||||
// and make sure we don't store a null value.
|
||||
|
||||
var result = DictionaryCacheProviderBase.GetSafeLazy(getCacheItem);
|
||||
var value = result.Value; // force evaluation now
|
||||
if (value == null) return; // do not store null values (backward compat)
|
||||
|
||||
var policy = GetPolicy(timeout, isSliding, removedCallback, dependentFiles);
|
||||
//NOTE: This does an add or update
|
||||
MemoryCache.Set(cacheKey, result, policy);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private static CacheItemPolicy GetPolicy(TimeSpan? timeout = null, bool isSliding = false, CacheItemRemovedCallback removedCallback = null, string[] dependentFiles = null)
|
||||
{
|
||||
var absolute = isSliding ? ObjectCache.InfiniteAbsoluteExpiration : (timeout == null ? ObjectCache.InfiniteAbsoluteExpiration : DateTime.Now.Add(timeout.Value));
|
||||
@@ -13,16 +13,16 @@ namespace Umbraco.Core.Cache
|
||||
internal abstract class RepositoryCachePolicyBase<TEntity, TId> : IRepositoryCachePolicy<TEntity, TId>
|
||||
where TEntity : class, IEntity
|
||||
{
|
||||
private readonly IRuntimeCacheProvider _globalCache;
|
||||
private readonly IAppPolicedCache _globalCache;
|
||||
private readonly IScopeAccessor _scopeAccessor;
|
||||
|
||||
protected RepositoryCachePolicyBase(IRuntimeCacheProvider globalCache, IScopeAccessor scopeAccessor)
|
||||
protected RepositoryCachePolicyBase(IAppPolicedCache globalCache, IScopeAccessor scopeAccessor)
|
||||
{
|
||||
_globalCache = globalCache ?? throw new ArgumentNullException(nameof(globalCache));
|
||||
_scopeAccessor = scopeAccessor ?? throw new ArgumentNullException(nameof(scopeAccessor));
|
||||
}
|
||||
|
||||
protected IRuntimeCacheProvider Cache
|
||||
protected IAppPolicedCache Cache
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -32,9 +32,9 @@ namespace Umbraco.Core.Cache
|
||||
case RepositoryCacheMode.Default:
|
||||
return _globalCache;
|
||||
case RepositoryCacheMode.Scoped:
|
||||
return ambientScope.IsolatedRuntimeCache.GetOrCreateCache<TEntity>();
|
||||
return ambientScope.IsolatedCaches.GetOrCreate<TEntity>();
|
||||
case RepositoryCacheMode.None:
|
||||
return NullCacheProvider.Instance;
|
||||
return NoAppCache.Instance;
|
||||
default:
|
||||
throw new NotSupportedException($"Repository cache mode {ambientScope.RepositoryCacheMode} is not supported.");
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace Umbraco.Core.Cache
|
||||
internal class SingleItemsOnlyRepositoryCachePolicy<TEntity, TId> : DefaultRepositoryCachePolicy<TEntity, TId>
|
||||
where TEntity : class, IEntity
|
||||
{
|
||||
public SingleItemsOnlyRepositoryCachePolicy(IRuntimeCacheProvider cache, IScopeAccessor scopeAccessor, RepositoryCachePolicyOptions options)
|
||||
public SingleItemsOnlyRepositoryCachePolicy(IAppPolicedCache cache, IScopeAccessor scopeAccessor, RepositoryCachePolicyOptions options)
|
||||
: base(cache, scopeAccessor, options)
|
||||
{ }
|
||||
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a cache provider that statically caches item in a concurrent dictionary.
|
||||
/// </summary>
|
||||
public class StaticCacheProvider : ICacheProvider
|
||||
{
|
||||
internal readonly ConcurrentDictionary<string, object> StaticCache = new ConcurrentDictionary<string, object>();
|
||||
|
||||
public virtual void ClearAllCache()
|
||||
{
|
||||
StaticCache.Clear();
|
||||
}
|
||||
|
||||
public virtual void ClearCacheItem(string key)
|
||||
{
|
||||
object val;
|
||||
StaticCache.TryRemove(key, out val);
|
||||
}
|
||||
|
||||
public virtual void ClearCacheObjectTypes(string typeName)
|
||||
{
|
||||
StaticCache.RemoveAll(kvp => kvp.Value != null && kvp.Value.GetType().ToString().InvariantEquals(typeName));
|
||||
}
|
||||
|
||||
public virtual void ClearCacheObjectTypes<T>()
|
||||
{
|
||||
var typeOfT = typeof(T);
|
||||
StaticCache.RemoveAll(kvp => kvp.Value != null && kvp.Value.GetType() == typeOfT);
|
||||
}
|
||||
|
||||
public virtual void ClearCacheObjectTypes<T>(Func<string, T, bool> predicate)
|
||||
{
|
||||
var typeOfT = typeof(T);
|
||||
StaticCache.RemoveAll(kvp => kvp.Value != null && kvp.Value.GetType() == typeOfT && predicate(kvp.Key, (T)kvp.Value));
|
||||
}
|
||||
|
||||
public virtual void ClearCacheByKeySearch(string keyStartsWith)
|
||||
{
|
||||
StaticCache.RemoveAll(kvp => kvp.Key.InvariantStartsWith(keyStartsWith));
|
||||
}
|
||||
|
||||
public virtual void ClearCacheByKeyExpression(string regexString)
|
||||
{
|
||||
StaticCache.RemoveAll(kvp => Regex.IsMatch(kvp.Key, regexString));
|
||||
}
|
||||
|
||||
public virtual IEnumerable<object> GetCacheItemsByKeySearch(string keyStartsWith)
|
||||
{
|
||||
return (from KeyValuePair<string, object> c in StaticCache
|
||||
where c.Key.InvariantStartsWith(keyStartsWith)
|
||||
select c.Value).ToList();
|
||||
}
|
||||
|
||||
public IEnumerable<object> GetCacheItemsByKeyExpression(string regexString)
|
||||
{
|
||||
return (from KeyValuePair<string, object> c in StaticCache
|
||||
where Regex.IsMatch(c.Key, regexString)
|
||||
select c.Value).ToList();
|
||||
}
|
||||
|
||||
public virtual object GetCacheItem(string cacheKey)
|
||||
{
|
||||
var result = StaticCache[cacheKey];
|
||||
return result;
|
||||
}
|
||||
|
||||
public virtual object GetCacheItem(string cacheKey, Func<object> getCacheItem)
|
||||
{
|
||||
return StaticCache.GetOrAdd(cacheKey, key => getCacheItem());
|
||||
}
|
||||
}
|
||||
}
|
||||
+44
-74
@@ -4,14 +4,15 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Web.Caching;
|
||||
using CacheItemPriority = System.Web.Caching.CacheItemPriority;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// Implements <see cref="IAppPolicedCache"/> on top of a <see cref="System.Web.Caching.Cache"/>.
|
||||
/// A CacheProvider that wraps the logic of the HttpRuntime.Cache
|
||||
/// </summary>
|
||||
internal class HttpRuntimeCacheProvider : DictionaryCacheProviderBase, IRuntimeCacheProvider
|
||||
/// <remarks>The underlying cache is expected to be HttpRuntime.Cache.</remarks>
|
||||
internal class WebCachingAppCache : FastDictionaryAppCacheBase, IAppPolicedCache
|
||||
{
|
||||
// locker object that supports upgradeable read locking
|
||||
// does not need to support recursion if we implement the cache correctly and ensure
|
||||
@@ -21,16 +22,43 @@ namespace Umbraco.Core.Cache
|
||||
private readonly System.Web.Caching.Cache _cache;
|
||||
|
||||
/// <summary>
|
||||
/// Used for debugging
|
||||
/// Initializes a new instance of the <see cref="WebCachingAppCache"/> class.
|
||||
/// </summary>
|
||||
internal Guid InstanceId { get; private set; }
|
||||
|
||||
public HttpRuntimeCacheProvider(System.Web.Caching.Cache cache)
|
||||
public WebCachingAppCache(System.Web.Caching.Cache cache)
|
||||
{
|
||||
_cache = cache;
|
||||
InstanceId = Guid.NewGuid();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override object Get(string key, Func<object> factory)
|
||||
{
|
||||
return Get(key, factory, null, dependentFiles: null);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public object Get(string key, Func<object> factory, TimeSpan? timeout, bool isSliding = false, CacheItemPriority priority = CacheItemPriority.Normal, CacheItemRemovedCallback removedCallback = null, string[] dependentFiles = null)
|
||||
{
|
||||
CacheDependency dependency = null;
|
||||
if (dependentFiles != null && dependentFiles.Any())
|
||||
{
|
||||
dependency = new CacheDependency(dependentFiles);
|
||||
}
|
||||
return Get(key, factory, timeout, isSliding, priority, removedCallback, dependency);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Insert(string key, Func<object> factory, TimeSpan? timeout = null, bool isSliding = false, CacheItemPriority priority = CacheItemPriority.Normal, CacheItemRemovedCallback removedCallback = null, string[] dependentFiles = null)
|
||||
{
|
||||
CacheDependency dependency = null;
|
||||
if (dependentFiles != null && dependentFiles.Any())
|
||||
{
|
||||
dependency = new CacheDependency(dependentFiles);
|
||||
}
|
||||
Insert(key, factory, timeout, isSliding, priority, removedCallback, dependency);
|
||||
}
|
||||
|
||||
#region Dictionary
|
||||
|
||||
protected override IEnumerable<DictionaryEntry> GetDictionaryEntries()
|
||||
{
|
||||
const string prefix = CacheItemPrefix + "-";
|
||||
@@ -48,6 +76,8 @@ namespace Umbraco.Core.Cache
|
||||
return _cache.Get(key);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Lock
|
||||
|
||||
protected override void EnterReadLock()
|
||||
@@ -74,33 +104,9 @@ namespace Umbraco.Core.Cache
|
||||
|
||||
#endregion
|
||||
|
||||
#region Get
|
||||
|
||||
/// <summary>
|
||||
/// Gets (and adds if necessary) an item from the cache with all of the default parameters
|
||||
/// </summary>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
/// <returns></returns>
|
||||
public override object GetCacheItem(string cacheKey, Func<object> getCacheItem)
|
||||
private object Get(string key, Func<object> factory, TimeSpan? timeout, bool isSliding = false, CacheItemPriority priority = CacheItemPriority.Normal, CacheItemRemovedCallback removedCallback = null, CacheDependency dependency = null)
|
||||
{
|
||||
return GetCacheItem(cacheKey, getCacheItem, null, dependentFiles: null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This overload is here for legacy purposes
|
||||
/// </summary>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
/// <param name="timeout"></param>
|
||||
/// <param name="isSliding"></param>
|
||||
/// <param name="priority"></param>
|
||||
/// <param name="removedCallback"></param>
|
||||
/// <param name="dependency"></param>
|
||||
/// <returns></returns>
|
||||
internal object GetCacheItem(string cacheKey, Func<object> getCacheItem, TimeSpan? timeout, bool isSliding = false, CacheItemPriority priority = CacheItemPriority.Normal, CacheItemRemovedCallback removedCallback = null, CacheDependency dependency = null)
|
||||
{
|
||||
cacheKey = GetCacheKey(cacheKey);
|
||||
key = GetCacheKey(key);
|
||||
|
||||
// NOTE - because we don't know what getCacheItem does, how long it will take and whether it will hang,
|
||||
// getCacheItem should run OUTSIDE of the global application lock else we run into lock contention and
|
||||
@@ -133,7 +139,7 @@ namespace Umbraco.Core.Cache
|
||||
try
|
||||
{
|
||||
_locker.EnterReadLock();
|
||||
result = _cache.Get(cacheKey) as Lazy<object>; // null if key not found
|
||||
result = _cache.Get(key) as Lazy<object>; // null if key not found
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -145,7 +151,7 @@ namespace Umbraco.Core.Cache
|
||||
|
||||
using (var lck = new UpgradeableReadLock(_locker))
|
||||
{
|
||||
result = _cache.Get(cacheKey) as Lazy<object>; // null if key not found
|
||||
result = _cache.Get(key) as Lazy<object>; // null if key not found
|
||||
|
||||
// cannot create value within the lock, so if result.IsValueCreated is false, just
|
||||
// do nothing here - means that if creation throws, a race condition could cause
|
||||
@@ -153,13 +159,13 @@ namespace Umbraco.Core.Cache
|
||||
|
||||
if (result == null || GetSafeLazyValue(result, true) == null) // get non-created as NonCreatedValue & exceptions as null
|
||||
{
|
||||
result = GetSafeLazy(getCacheItem);
|
||||
result = GetSafeLazy(factory);
|
||||
var absolute = isSliding ? System.Web.Caching.Cache.NoAbsoluteExpiration : (timeout == null ? System.Web.Caching.Cache.NoAbsoluteExpiration : DateTime.Now.Add(timeout.Value));
|
||||
var sliding = isSliding == false ? System.Web.Caching.Cache.NoSlidingExpiration : (timeout ?? System.Web.Caching.Cache.NoSlidingExpiration);
|
||||
|
||||
lck.UpgradeToWriteLock();
|
||||
//NOTE: 'Insert' on System.Web.Caching.Cache actually does an add or update!
|
||||
_cache.Insert(cacheKey, result, dependency, absolute, sliding, priority, removedCallback);
|
||||
_cache.Insert(key, result, dependency, absolute, sliding, priority, removedCallback);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,31 +181,7 @@ namespace Umbraco.Core.Cache
|
||||
return value;
|
||||
}
|
||||
|
||||
public object GetCacheItem(string cacheKey, Func<object> getCacheItem, TimeSpan? timeout, bool isSliding = false, CacheItemPriority priority = CacheItemPriority.Normal, CacheItemRemovedCallback removedCallback = null, string[] dependentFiles = null)
|
||||
{
|
||||
CacheDependency dependency = null;
|
||||
if (dependentFiles != null && dependentFiles.Any())
|
||||
{
|
||||
dependency = new CacheDependency(dependentFiles);
|
||||
}
|
||||
return GetCacheItem(cacheKey, getCacheItem, timeout, isSliding, priority, removedCallback, dependency);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Insert
|
||||
|
||||
/// <summary>
|
||||
/// This overload is here for legacy purposes
|
||||
/// </summary>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
/// <param name="timeout"></param>
|
||||
/// <param name="isSliding"></param>
|
||||
/// <param name="priority"></param>
|
||||
/// <param name="removedCallback"></param>
|
||||
/// <param name="dependency"></param>
|
||||
internal void InsertCacheItem(string cacheKey, Func<object> getCacheItem, TimeSpan? timeout = null, bool isSliding = false, CacheItemPriority priority = CacheItemPriority.Normal, CacheItemRemovedCallback removedCallback = null, CacheDependency dependency = null)
|
||||
private void Insert(string cacheKey, Func<object> getCacheItem, TimeSpan? timeout = null, bool isSliding = false, CacheItemPriority priority = CacheItemPriority.Normal, CacheItemRemovedCallback removedCallback = null, CacheDependency dependency = null)
|
||||
{
|
||||
// NOTE - here also we must insert a Lazy<object> but we can evaluate it right now
|
||||
// and make sure we don't store a null value.
|
||||
@@ -225,17 +207,5 @@ namespace Umbraco.Core.Cache
|
||||
_locker.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
|
||||
public void InsertCacheItem(string cacheKey, Func<object> getCacheItem, TimeSpan? timeout = null, bool isSliding = false, CacheItemPriority priority = CacheItemPriority.Normal, CacheItemRemovedCallback removedCallback = null, string[] dependentFiles = null)
|
||||
{
|
||||
CacheDependency dependency = null;
|
||||
if (dependentFiles != null && dependentFiles.Any())
|
||||
{
|
||||
dependency = new CacheDependency(dependentFiles);
|
||||
}
|
||||
InsertCacheItem(cacheKey, getCacheItem, timeout, isSliding, priority, removedCallback, dependency);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -29,7 +29,7 @@ namespace Umbraco.Core.Composing
|
||||
{
|
||||
private const string CacheKey = "umbraco-types.list";
|
||||
|
||||
private readonly IRuntimeCacheProvider _runtimeCache;
|
||||
private readonly IAppPolicedCache _runtimeCache;
|
||||
private readonly IProfilingLogger _logger;
|
||||
|
||||
private readonly Dictionary<CompositeTypeTypeKey, TypeList> _types = new Dictionary<CompositeTypeTypeKey, TypeList>();
|
||||
@@ -51,7 +51,7 @@ namespace Umbraco.Core.Composing
|
||||
/// <param name="runtimeCache">The application runtime cache.</param>
|
||||
/// <param name="localTempStorage">Files storage mode.</param>
|
||||
/// <param name="logger">A profiling logger.</param>
|
||||
public TypeLoader(IRuntimeCacheProvider runtimeCache, LocalTempStorage localTempStorage, IProfilingLogger logger)
|
||||
public TypeLoader(IAppPolicedCache runtimeCache, LocalTempStorage localTempStorage, IProfilingLogger logger)
|
||||
: this(runtimeCache, localTempStorage, logger, true)
|
||||
{ }
|
||||
|
||||
@@ -62,7 +62,7 @@ namespace Umbraco.Core.Composing
|
||||
/// <param name="localTempStorage">Files storage mode.</param>
|
||||
/// <param name="logger">A profiling logger.</param>
|
||||
/// <param name="detectChanges">Whether to detect changes using hashes.</param>
|
||||
internal TypeLoader(IRuntimeCacheProvider runtimeCache, LocalTempStorage localTempStorage, IProfilingLogger logger, bool detectChanges)
|
||||
internal TypeLoader(IAppPolicedCache runtimeCache, LocalTempStorage localTempStorage, IProfilingLogger logger, bool detectChanges)
|
||||
{
|
||||
_runtimeCache = runtimeCache ?? throw new ArgumentNullException(nameof(runtimeCache));
|
||||
_localTempStorage = localTempStorage == LocalTempStorage.Unknown ? LocalTempStorage.Default : localTempStorage;
|
||||
@@ -478,7 +478,7 @@ namespace Umbraco.Core.Composing
|
||||
var typesHashFilePath = GetTypesHashFilePath();
|
||||
DeleteFile(typesHashFilePath, FileDeleteTimeout);
|
||||
|
||||
_runtimeCache.ClearCacheItem(CacheKey);
|
||||
_runtimeCache.Clear(CacheKey);
|
||||
}
|
||||
|
||||
private Stream GetFileStream(string path, FileMode fileMode, FileAccess fileAccess, FileShare fileShare, int timeoutMilliseconds)
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace Umbraco.Core
|
||||
configs.Add(() => new CoreDebug());
|
||||
|
||||
// GridConfig depends on runtime caches, manifest parsers... and cannot be available during composition
|
||||
configs.Add<IGridConfig>(factory => new GridConfig(factory.GetInstance<ILogger>(), factory.GetInstance<IRuntimeCacheProvider>(), configDir, factory.GetInstance<IRuntimeState>().Debug));
|
||||
configs.Add<IGridConfig>(factory => new GridConfig(factory.GetInstance<ILogger>(), factory.GetInstance<IAppPolicedCache>(), configDir, factory.GetInstance<IRuntimeState>().Debug));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ namespace Umbraco.Core.Configuration.Grid
|
||||
{
|
||||
class GridConfig : IGridConfig
|
||||
{
|
||||
public GridConfig(ILogger logger, IRuntimeCacheProvider runtimeCache, DirectoryInfo configFolder, bool isDebug)
|
||||
public GridConfig(ILogger logger, IAppPolicedCache runtimeCache, DirectoryInfo configFolder, bool isDebug)
|
||||
{
|
||||
EditorsConfig = new GridEditorsConfig(logger, runtimeCache, configFolder, isDebug);
|
||||
}
|
||||
|
||||
@@ -13,11 +13,11 @@ namespace Umbraco.Core.Configuration.Grid
|
||||
internal class GridEditorsConfig : IGridEditorsConfig
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private readonly IRuntimeCacheProvider _runtimeCache;
|
||||
private readonly IAppPolicedCache _runtimeCache;
|
||||
private readonly DirectoryInfo _configFolder;
|
||||
private readonly bool _isDebug;
|
||||
|
||||
public GridEditorsConfig(ILogger logger, IRuntimeCacheProvider runtimeCache, DirectoryInfo configFolder, bool isDebug)
|
||||
public GridEditorsConfig(ILogger logger, IAppPolicedCache runtimeCache, DirectoryInfo configFolder, bool isDebug)
|
||||
{
|
||||
_logger = logger;
|
||||
_runtimeCache = runtimeCache;
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace Umbraco.Core.Manifest
|
||||
{
|
||||
private static readonly string Utf8Preamble = Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble());
|
||||
|
||||
private readonly IRuntimeCacheProvider _cache;
|
||||
private readonly IAppPolicedCache _cache;
|
||||
private readonly ILogger _logger;
|
||||
private readonly ManifestValueValidatorCollection _validators;
|
||||
|
||||
@@ -29,14 +29,14 @@ namespace Umbraco.Core.Manifest
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ManifestParser"/> class.
|
||||
/// </summary>
|
||||
public ManifestParser(IRuntimeCacheProvider cache, ManifestValueValidatorCollection validators, ILogger logger)
|
||||
public ManifestParser(IAppPolicedCache cache, ManifestValueValidatorCollection validators, ILogger logger)
|
||||
: this(cache, validators, "~/App_Plugins", logger)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ManifestParser"/> class.
|
||||
/// </summary>
|
||||
private ManifestParser(IRuntimeCacheProvider cache, ManifestValueValidatorCollection validators, string path, ILogger logger)
|
||||
private ManifestParser(IAppPolicedCache cache, ManifestValueValidatorCollection validators, string path, ILogger logger)
|
||||
{
|
||||
_cache = cache ?? throw new ArgumentNullException(nameof(cache));
|
||||
_validators = validators ?? throw new ArgumentNullException(nameof(validators));
|
||||
|
||||
@@ -54,7 +54,7 @@ namespace Umbraco.Core.Models
|
||||
/// <returns>
|
||||
/// A list of 5 different sized avatar URLs
|
||||
/// </returns>
|
||||
internal static string[] GetUserAvatarUrls(this IUser user, ICacheProvider staticCache)
|
||||
internal static string[] GetUserAvatarUrls(this IUser user, IAppCache staticCache)
|
||||
{
|
||||
// If FIPS is required, never check the Gravatar service as it only supports MD5 hashing.
|
||||
// Unfortunately, if the FIPS setting is enabled on Windows, using MD5 will throw an exception
|
||||
|
||||
@@ -86,7 +86,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
Database.Update(dto);
|
||||
entity.ResetDirtyProperties();
|
||||
|
||||
IsolatedCache.ClearCacheItem(RepositoryCacheKeys.GetKey<IConsent>(entity.Id));
|
||||
IsolatedCache.Clear(RepositoryCacheKeys.GetKey<IConsent>(entity.Id));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -174,8 +174,8 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
entity.ResetDirtyProperties();
|
||||
|
||||
//Clear the cache entries that exist by uniqueid/item key
|
||||
IsolatedCache.ClearCacheItem(RepositoryCacheKeys.GetKey<IDictionaryItem>(entity.ItemKey));
|
||||
IsolatedCache.ClearCacheItem(RepositoryCacheKeys.GetKey<IDictionaryItem>(entity.Key));
|
||||
IsolatedCache.Clear(RepositoryCacheKeys.GetKey<IDictionaryItem>(entity.ItemKey));
|
||||
IsolatedCache.Clear(RepositoryCacheKeys.GetKey<IDictionaryItem>(entity.Key));
|
||||
}
|
||||
|
||||
protected override void PersistDeletedItem(IDictionaryItem entity)
|
||||
@@ -186,8 +186,8 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
Database.Delete<DictionaryDto>("WHERE id = @Id", new { Id = entity.Key });
|
||||
|
||||
//Clear the cache entries that exist by uniqueid/item key
|
||||
IsolatedCache.ClearCacheItem(RepositoryCacheKeys.GetKey<IDictionaryItem>(entity.ItemKey));
|
||||
IsolatedCache.ClearCacheItem(RepositoryCacheKeys.GetKey<IDictionaryItem>(entity.Key));
|
||||
IsolatedCache.Clear(RepositoryCacheKeys.GetKey<IDictionaryItem>(entity.ItemKey));
|
||||
IsolatedCache.Clear(RepositoryCacheKeys.GetKey<IDictionaryItem>(entity.Key));
|
||||
|
||||
entity.DeleteDate = DateTime.Now;
|
||||
}
|
||||
@@ -203,8 +203,8 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
Database.Delete<DictionaryDto>("WHERE id = @Id", new { Id = dto.UniqueId });
|
||||
|
||||
//Clear the cache entries that exist by uniqueid/item key
|
||||
IsolatedCache.ClearCacheItem(RepositoryCacheKeys.GetKey<IDictionaryItem>(dto.Key));
|
||||
IsolatedCache.ClearCacheItem(RepositoryCacheKeys.GetKey<IDictionaryItem>(dto.UniqueId));
|
||||
IsolatedCache.Clear(RepositoryCacheKeys.GetKey<IDictionaryItem>(dto.Key));
|
||||
IsolatedCache.Clear(RepositoryCacheKeys.GetKey<IDictionaryItem>(dto.UniqueId));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
|
||||
protected AppCaches GlobalCache { get; }
|
||||
|
||||
protected IRuntimeCacheProvider GlobalIsolatedCache => GlobalCache.IsolatedRuntimeCache.GetOrCreateCache<TEntity>();
|
||||
protected IAppPolicedCache GlobalIsolatedCache => GlobalCache.IsolatedCaches.GetOrCreate<TEntity>();
|
||||
|
||||
protected IScopeAccessor ScopeAccessor { get; }
|
||||
|
||||
@@ -60,18 +60,18 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
/// Gets the isolated cache.
|
||||
/// </summary>
|
||||
/// <remarks>Depends on the ambient scope cache mode.</remarks>
|
||||
protected IRuntimeCacheProvider IsolatedCache
|
||||
protected IAppPolicedCache IsolatedCache
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (AmbientScope.RepositoryCacheMode)
|
||||
{
|
||||
case RepositoryCacheMode.Default:
|
||||
return GlobalCache.IsolatedRuntimeCache.GetOrCreateCache<TEntity>();
|
||||
return GlobalCache.IsolatedCaches.GetOrCreate<TEntity>();
|
||||
case RepositoryCacheMode.Scoped:
|
||||
return AmbientScope.IsolatedRuntimeCache.GetOrCreateCache<TEntity>();
|
||||
return AmbientScope.IsolatedCaches.GetOrCreate<TEntity>();
|
||||
case RepositoryCacheMode.None:
|
||||
return NullCacheProvider.Instance;
|
||||
return NoAppCache.Instance;
|
||||
default:
|
||||
throw new Exception("oops: cache mode.");
|
||||
}
|
||||
@@ -157,7 +157,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
/// <summary>
|
||||
/// Adds or Updates an entity of type TEntity
|
||||
/// </summary>
|
||||
/// <remarks>This method is backed by an <see cref="IRuntimeCacheProvider"/> cache</remarks>
|
||||
/// <remarks>This method is backed by an <see cref="IAppPolicedCache"/> cache</remarks>
|
||||
/// <param name="entity"></param>
|
||||
public void Save(TEntity entity)
|
||||
{
|
||||
|
||||
@@ -332,10 +332,10 @@ namespace Umbraco.Core.Runtime
|
||||
// is overriden by the web runtime
|
||||
|
||||
return new AppCaches(
|
||||
new DeepCloneRuntimeCacheProvider(new ObjectCacheRuntimeCacheProvider()),
|
||||
new StaticCacheProvider(),
|
||||
NullCacheProvider.Instance,
|
||||
new IsolatedRuntimeCache(type => new DeepCloneRuntimeCacheProvider(new ObjectCacheRuntimeCacheProvider())));
|
||||
new DeepCloneAppCache(new ObjectCacheAppCache()),
|
||||
new DictionaryCacheProvider(),
|
||||
NoAppCache.Instance,
|
||||
new IsolatedCaches(type => new DeepCloneAppCache(new ObjectCacheAppCache())));
|
||||
}
|
||||
|
||||
// by default, returns null, meaning that Umbraco should auto-detect the application root path.
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace Umbraco.Core.Scoping
|
||||
/// <summary>
|
||||
/// Gets the scope isolated cache.
|
||||
/// </summary>
|
||||
IsolatedRuntimeCache IsolatedRuntimeCache { get; }
|
||||
IsolatedCaches IsolatedCaches { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Completes the scope.
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace Umbraco.Core.Scoping
|
||||
private bool _disposed;
|
||||
private bool? _completed;
|
||||
|
||||
private IsolatedRuntimeCache _isolatedRuntimeCache;
|
||||
private IsolatedCaches _isolatedCaches;
|
||||
private IUmbracoDatabase _database;
|
||||
private EventMessages _messages;
|
||||
private ICompletable _fscope;
|
||||
@@ -177,14 +177,14 @@ namespace Umbraco.Core.Scoping
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IsolatedRuntimeCache IsolatedRuntimeCache
|
||||
public IsolatedCaches IsolatedCaches
|
||||
{
|
||||
get
|
||||
{
|
||||
if (ParentScope != null) return ParentScope.IsolatedRuntimeCache;
|
||||
if (ParentScope != null) return ParentScope.IsolatedCaches;
|
||||
|
||||
return _isolatedRuntimeCache ?? (_isolatedRuntimeCache
|
||||
= new IsolatedRuntimeCache(type => new DeepCloneRuntimeCacheProvider(new ObjectCacheRuntimeCacheProvider())));
|
||||
return _isolatedCaches ?? (_isolatedCaches
|
||||
= new IsolatedCaches(type => new DeepCloneAppCache(new ObjectCacheAppCache())));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace Umbraco.Core.Services.Implement
|
||||
public class LocalizedTextServiceFileSources
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private readonly IRuntimeCacheProvider _cache;
|
||||
private readonly IAppPolicedCache _cache;
|
||||
private readonly IEnumerable<LocalizedTextServiceSupplementaryFileSource> _supplementFileSources;
|
||||
private readonly DirectoryInfo _fileSourceFolder;
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace Umbraco.Core.Services.Implement
|
||||
/// <param name="supplementFileSources"></param>
|
||||
public LocalizedTextServiceFileSources(
|
||||
ILogger logger,
|
||||
IRuntimeCacheProvider cache,
|
||||
IAppPolicedCache cache,
|
||||
DirectoryInfo fileSourceFolder,
|
||||
IEnumerable<LocalizedTextServiceSupplementaryFileSource> supplementFileSources)
|
||||
{
|
||||
@@ -140,7 +140,7 @@ namespace Umbraco.Core.Services.Implement
|
||||
/// <param name="logger"></param>
|
||||
/// <param name="cache"></param>
|
||||
/// <param name="fileSourceFolder"></param>
|
||||
public LocalizedTextServiceFileSources(ILogger logger, IRuntimeCacheProvider cache, DirectoryInfo fileSourceFolder)
|
||||
public LocalizedTextServiceFileSources(ILogger logger, IAppPolicedCache cache, DirectoryInfo fileSourceFolder)
|
||||
: this(logger, cache, fileSourceFolder, Enumerable.Empty<LocalizedTextServiceSupplementaryFileSource>())
|
||||
{
|
||||
|
||||
|
||||
@@ -109,6 +109,7 @@
|
||||
<Compile Include="Attempt.cs" />
|
||||
<Compile Include="AttemptOfTResult.cs" />
|
||||
<Compile Include="AttemptOfTResultTStatus.cs" />
|
||||
<Compile Include="Cache\AppPolicedCacheDictionary.cs" />
|
||||
<Compile Include="Components\AuditEventsComponent.cs" />
|
||||
<Compile Include="BindingRedirects.cs" />
|
||||
<Compile Include="Cache\AppCaches.cs" />
|
||||
@@ -118,29 +119,29 @@
|
||||
<Compile Include="Cache\CacheRefresherCollection.cs" />
|
||||
<Compile Include="Cache\CacheRefresherCollectionBuilder.cs" />
|
||||
<Compile Include="Cache\CacheRefresherEventArgs.cs" />
|
||||
<Compile Include="Cache\DeepCloneRuntimeCacheProvider.cs" />
|
||||
<Compile Include="Cache\DeepCloneAppCache.cs" />
|
||||
<Compile Include="Cache\DefaultRepositoryCachePolicy.cs" />
|
||||
<Compile Include="Cache\DictionaryCacheProvider.cs" />
|
||||
<Compile Include="Cache\DictionaryCacheProviderBase.cs" />
|
||||
<Compile Include="Cache\FastDictionaryCacheProvider.cs" />
|
||||
<Compile Include="Cache\FastDictionaryAppCacheBase.cs" />
|
||||
<Compile Include="Cache\FullDataSetRepositoryCachePolicy.cs" />
|
||||
<Compile Include="Cache\HttpRequestCacheProvider.cs" />
|
||||
<Compile Include="Cache\HttpRuntimeCacheProvider.cs" />
|
||||
<Compile Include="Cache\ICacheProvider.cs" />
|
||||
<Compile Include="Cache\HttpRequestAppCache.cs" />
|
||||
<Compile Include="Cache\WebCachingAppCache.cs" />
|
||||
<Compile Include="Cache\IAppCache.cs" />
|
||||
<Compile Include="Cache\ICacheRefresher.cs" />
|
||||
<Compile Include="Cache\IJsonCacheRefresher.cs" />
|
||||
<Compile Include="Cache\IPayloadCacheRefresher.cs" />
|
||||
<Compile Include="Cache\IRepositoryCachePolicy.cs" />
|
||||
<Compile Include="Cache\IRuntimeCacheProvider.cs" />
|
||||
<Compile Include="Cache\IsolatedRuntimeCache.cs" />
|
||||
<Compile Include="Cache\IAppPolicedCache.cs" />
|
||||
<Compile Include="Cache\IsolatedCaches.cs" />
|
||||
<Compile Include="Cache\JsonCacheRefresherBase.cs" />
|
||||
<Compile Include="Cache\NoCacheRepositoryCachePolicy.cs" />
|
||||
<Compile Include="Cache\NullCacheProvider.cs" />
|
||||
<Compile Include="Cache\ObjectCacheRuntimeCacheProvider.cs" />
|
||||
<Compile Include="Cache\NoAppCache.cs" />
|
||||
<Compile Include="Cache\ObjectCacheAppCache.cs" />
|
||||
<Compile Include="Cache\PayloadCacheRefresherBase.cs" />
|
||||
<Compile Include="Cache\RepositoryCachePolicyBase.cs" />
|
||||
<Compile Include="Cache\RepositoryCachePolicyOptions.cs" />
|
||||
<Compile Include="Cache\SingleItemsOnlyRepositoryCachePolicy.cs" />
|
||||
<Compile Include="Cache\StaticCacheProvider.cs" />
|
||||
<Compile Include="Cache\DictionaryCacheProvider.cs" />
|
||||
<Compile Include="Cache\TypedCacheRefresherBase.cs" />
|
||||
<Compile Include="CodeAnnotations\FriendlyNameAttribute.cs" />
|
||||
<Compile Include="CodeAnnotations\UmbracoObjectTypeAttribute.cs" />
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Umbraco.Tests.Cache
|
||||
{
|
||||
public abstract class CacheProviderTests
|
||||
{
|
||||
internal abstract ICacheProvider Provider { get; }
|
||||
internal abstract IAppCache Provider { get; }
|
||||
protected abstract int GetTotalItemCount { get; }
|
||||
|
||||
[SetUp]
|
||||
@@ -21,7 +21,7 @@ namespace Umbraco.Tests.Cache
|
||||
[TearDown]
|
||||
public virtual void TearDown()
|
||||
{
|
||||
Provider.ClearAllCache();
|
||||
Provider.Clear();
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -32,11 +32,11 @@ namespace Umbraco.Tests.Cache
|
||||
Assert.Ignore("Do not run for StaticCacheProvider.");
|
||||
|
||||
Exception exception = null;
|
||||
var result = Provider.GetCacheItem("blah", () =>
|
||||
var result = Provider.Get("blah", () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var result2 = Provider.GetCacheItem("blah");
|
||||
var result2 = Provider.Get("blah");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -56,7 +56,7 @@ namespace Umbraco.Tests.Cache
|
||||
object result;
|
||||
try
|
||||
{
|
||||
result = Provider.GetCacheItem("Blah", () =>
|
||||
result = Provider.Get("Blah", () =>
|
||||
{
|
||||
counter++;
|
||||
throw new Exception("Do not cache this");
|
||||
@@ -66,7 +66,7 @@ namespace Umbraco.Tests.Cache
|
||||
|
||||
try
|
||||
{
|
||||
result = Provider.GetCacheItem("Blah", () =>
|
||||
result = Provider.Get("Blah", () =>
|
||||
{
|
||||
counter++;
|
||||
throw new Exception("Do not cache this");
|
||||
@@ -85,13 +85,13 @@ namespace Umbraco.Tests.Cache
|
||||
|
||||
object result;
|
||||
|
||||
result = Provider.GetCacheItem("Blah", () =>
|
||||
result = Provider.Get("Blah", () =>
|
||||
{
|
||||
counter++;
|
||||
return "";
|
||||
});
|
||||
|
||||
result = Provider.GetCacheItem("Blah", () =>
|
||||
result = Provider.Get("Blah", () =>
|
||||
{
|
||||
counter++;
|
||||
return "";
|
||||
@@ -108,14 +108,14 @@ namespace Umbraco.Tests.Cache
|
||||
var cacheContent2 = new MacroCacheContent(new LiteralControl(), "Test2");
|
||||
var cacheContent3 = new MacroCacheContent(new LiteralControl(), "Test3");
|
||||
var cacheContent4 = new LiteralControl();
|
||||
Provider.GetCacheItem("Test1", () => cacheContent1);
|
||||
Provider.GetCacheItem("Tester2", () => cacheContent2);
|
||||
Provider.GetCacheItem("Tes3", () => cacheContent3);
|
||||
Provider.GetCacheItem("different4", () => cacheContent4);
|
||||
Provider.Get("Test1", () => cacheContent1);
|
||||
Provider.Get("Tester2", () => cacheContent2);
|
||||
Provider.Get("Tes3", () => cacheContent3);
|
||||
Provider.Get("different4", () => cacheContent4);
|
||||
|
||||
Assert.AreEqual(4, GetTotalItemCount);
|
||||
|
||||
var result = Provider.GetCacheItemsByKeySearch("Tes");
|
||||
var result = Provider.SearchByKey("Tes");
|
||||
|
||||
Assert.AreEqual(3, result.Count());
|
||||
}
|
||||
@@ -127,14 +127,14 @@ namespace Umbraco.Tests.Cache
|
||||
var cacheContent2 = new MacroCacheContent(new LiteralControl(), "Test2");
|
||||
var cacheContent3 = new MacroCacheContent(new LiteralControl(), "Test3");
|
||||
var cacheContent4 = new LiteralControl();
|
||||
Provider.GetCacheItem("TTes1t", () => cacheContent1);
|
||||
Provider.GetCacheItem("Tester2", () => cacheContent2);
|
||||
Provider.GetCacheItem("Tes3", () => cacheContent3);
|
||||
Provider.GetCacheItem("different4", () => cacheContent4);
|
||||
Provider.Get("TTes1t", () => cacheContent1);
|
||||
Provider.Get("Tester2", () => cacheContent2);
|
||||
Provider.Get("Tes3", () => cacheContent3);
|
||||
Provider.Get("different4", () => cacheContent4);
|
||||
|
||||
Assert.AreEqual(4, GetTotalItemCount);
|
||||
|
||||
Provider.ClearCacheByKeyExpression("^\\w+es\\d.*");
|
||||
Provider.ClearByRegex("^\\w+es\\d.*");
|
||||
|
||||
Assert.AreEqual(2, GetTotalItemCount);
|
||||
}
|
||||
@@ -146,14 +146,14 @@ namespace Umbraco.Tests.Cache
|
||||
var cacheContent2 = new MacroCacheContent(new LiteralControl(), "Test2");
|
||||
var cacheContent3 = new MacroCacheContent(new LiteralControl(), "Test3");
|
||||
var cacheContent4 = new LiteralControl();
|
||||
Provider.GetCacheItem("Test1", () => cacheContent1);
|
||||
Provider.GetCacheItem("Tester2", () => cacheContent2);
|
||||
Provider.GetCacheItem("Tes3", () => cacheContent3);
|
||||
Provider.GetCacheItem("different4", () => cacheContent4);
|
||||
Provider.Get("Test1", () => cacheContent1);
|
||||
Provider.Get("Tester2", () => cacheContent2);
|
||||
Provider.Get("Tes3", () => cacheContent3);
|
||||
Provider.Get("different4", () => cacheContent4);
|
||||
|
||||
Assert.AreEqual(4, GetTotalItemCount);
|
||||
|
||||
Provider.ClearCacheByKeySearch("Test");
|
||||
Provider.ClearByKey("Test");
|
||||
|
||||
Assert.AreEqual(2, GetTotalItemCount);
|
||||
}
|
||||
@@ -165,15 +165,15 @@ namespace Umbraco.Tests.Cache
|
||||
var cacheContent2 = new MacroCacheContent(new LiteralControl(), "Test2");
|
||||
var cacheContent3 = new MacroCacheContent(new LiteralControl(), "Test3");
|
||||
var cacheContent4 = new LiteralControl();
|
||||
Provider.GetCacheItem("Test1", () => cacheContent1);
|
||||
Provider.GetCacheItem("Test2", () => cacheContent2);
|
||||
Provider.GetCacheItem("Test3", () => cacheContent3);
|
||||
Provider.GetCacheItem("Test4", () => cacheContent4);
|
||||
Provider.Get("Test1", () => cacheContent1);
|
||||
Provider.Get("Test2", () => cacheContent2);
|
||||
Provider.Get("Test3", () => cacheContent3);
|
||||
Provider.Get("Test4", () => cacheContent4);
|
||||
|
||||
Assert.AreEqual(4, GetTotalItemCount);
|
||||
|
||||
Provider.ClearCacheItem("Test1");
|
||||
Provider.ClearCacheItem("Test2");
|
||||
Provider.Clear("Test1");
|
||||
Provider.Clear("Test2");
|
||||
|
||||
Assert.AreEqual(2, GetTotalItemCount);
|
||||
}
|
||||
@@ -185,14 +185,14 @@ namespace Umbraco.Tests.Cache
|
||||
var cacheContent2 = new MacroCacheContent(new LiteralControl(), "Test2");
|
||||
var cacheContent3 = new MacroCacheContent(new LiteralControl(), "Test3");
|
||||
var cacheContent4 = new LiteralControl();
|
||||
Provider.GetCacheItem("Test1", () => cacheContent1);
|
||||
Provider.GetCacheItem("Test2", () => cacheContent2);
|
||||
Provider.GetCacheItem("Test3", () => cacheContent3);
|
||||
Provider.GetCacheItem("Test4", () => cacheContent4);
|
||||
Provider.Get("Test1", () => cacheContent1);
|
||||
Provider.Get("Test2", () => cacheContent2);
|
||||
Provider.Get("Test3", () => cacheContent3);
|
||||
Provider.Get("Test4", () => cacheContent4);
|
||||
|
||||
Assert.AreEqual(4, GetTotalItemCount);
|
||||
|
||||
Provider.ClearAllCache();
|
||||
Provider.Clear();
|
||||
|
||||
Assert.AreEqual(0, GetTotalItemCount);
|
||||
}
|
||||
@@ -201,7 +201,7 @@ namespace Umbraco.Tests.Cache
|
||||
public void Can_Add_When_Not_Available()
|
||||
{
|
||||
var cacheContent1 = new MacroCacheContent(new LiteralControl(), "Test1");
|
||||
Provider.GetCacheItem("Test1", () => cacheContent1);
|
||||
Provider.Get("Test1", () => cacheContent1);
|
||||
Assert.AreEqual(1, GetTotalItemCount);
|
||||
}
|
||||
|
||||
@@ -209,8 +209,8 @@ namespace Umbraco.Tests.Cache
|
||||
public void Can_Get_When_Available()
|
||||
{
|
||||
var cacheContent1 = new MacroCacheContent(new LiteralControl(), "Test1");
|
||||
var result = Provider.GetCacheItem("Test1", () => cacheContent1);
|
||||
var result2 = Provider.GetCacheItem("Test1", () => cacheContent1);
|
||||
var result = Provider.Get("Test1", () => cacheContent1);
|
||||
var result2 = Provider.Get("Test1", () => cacheContent1);
|
||||
Assert.AreEqual(1, GetTotalItemCount);
|
||||
Assert.AreEqual(result, result2);
|
||||
}
|
||||
@@ -222,15 +222,15 @@ namespace Umbraco.Tests.Cache
|
||||
var cacheContent2 = new MacroCacheContent(new LiteralControl(), "Test2");
|
||||
var cacheContent3 = new MacroCacheContent(new LiteralControl(), "Test3");
|
||||
var cacheContent4 = new LiteralControl();
|
||||
Provider.GetCacheItem("Test1", () => cacheContent1);
|
||||
Provider.GetCacheItem("Test2", () => cacheContent2);
|
||||
Provider.GetCacheItem("Test3", () => cacheContent3);
|
||||
Provider.GetCacheItem("Test4", () => cacheContent4);
|
||||
Provider.Get("Test1", () => cacheContent1);
|
||||
Provider.Get("Test2", () => cacheContent2);
|
||||
Provider.Get("Test3", () => cacheContent3);
|
||||
Provider.Get("Test4", () => cacheContent4);
|
||||
|
||||
Assert.AreEqual(4, GetTotalItemCount);
|
||||
|
||||
//Provider.ClearCacheObjectTypes("umbraco.MacroCacheContent");
|
||||
Provider.ClearCacheObjectTypes(typeof(MacroCacheContent).ToString());
|
||||
Provider.ClearOfType(typeof(MacroCacheContent).ToString());
|
||||
|
||||
Assert.AreEqual(1, GetTotalItemCount);
|
||||
}
|
||||
@@ -242,14 +242,14 @@ namespace Umbraco.Tests.Cache
|
||||
var cacheContent2 = new MacroCacheContent(new LiteralControl(), "Test2");
|
||||
var cacheContent3 = new MacroCacheContent(new LiteralControl(), "Test3");
|
||||
var cacheContent4 = new LiteralControl();
|
||||
Provider.GetCacheItem("Test1", () => cacheContent1);
|
||||
Provider.GetCacheItem("Test2", () => cacheContent2);
|
||||
Provider.GetCacheItem("Test3", () => cacheContent3);
|
||||
Provider.GetCacheItem("Test4", () => cacheContent4);
|
||||
Provider.Get("Test1", () => cacheContent1);
|
||||
Provider.Get("Test2", () => cacheContent2);
|
||||
Provider.Get("Test3", () => cacheContent3);
|
||||
Provider.Get("Test4", () => cacheContent4);
|
||||
|
||||
Assert.AreEqual(4, GetTotalItemCount);
|
||||
|
||||
Provider.ClearCacheObjectTypes<MacroCacheContent>();
|
||||
Provider.ClearOfType<MacroCacheContent>();
|
||||
|
||||
Assert.AreEqual(1, GetTotalItemCount);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace Umbraco.Tests.Cache
|
||||
[TestFixture]
|
||||
public class DeepCloneRuntimeCacheProviderTests : RuntimeCacheProviderTests
|
||||
{
|
||||
private DeepCloneRuntimeCacheProvider _provider;
|
||||
private DeepCloneAppCache _provider;
|
||||
|
||||
protected override int GetTotalItemCount
|
||||
{
|
||||
@@ -26,15 +26,15 @@ namespace Umbraco.Tests.Cache
|
||||
public override void Setup()
|
||||
{
|
||||
base.Setup();
|
||||
_provider = new DeepCloneRuntimeCacheProvider(new HttpRuntimeCacheProvider(HttpRuntime.Cache));
|
||||
_provider = new DeepCloneAppCache(new WebCachingAppCache(HttpRuntime.Cache));
|
||||
}
|
||||
|
||||
internal override ICacheProvider Provider
|
||||
internal override IAppCache Provider
|
||||
{
|
||||
get { return _provider; }
|
||||
}
|
||||
|
||||
internal override IRuntimeCacheProvider RuntimeProvider
|
||||
internal override IAppPolicedCache RuntimeProvider
|
||||
{
|
||||
get { return _provider; }
|
||||
}
|
||||
@@ -75,15 +75,15 @@ namespace Umbraco.Tests.Cache
|
||||
public void DoesNotCacheExceptions()
|
||||
{
|
||||
string value;
|
||||
Assert.Throws<Exception>(() => { value = (string)_provider.GetCacheItem("key", () => GetValue(1)); });
|
||||
Assert.Throws<Exception>(() => { value = (string)_provider.GetCacheItem("key", () => GetValue(2)); });
|
||||
Assert.Throws<Exception>(() => { value = (string)_provider.Get("key", () => GetValue(1)); });
|
||||
Assert.Throws<Exception>(() => { value = (string)_provider.Get("key", () => GetValue(2)); });
|
||||
|
||||
// does not throw
|
||||
value = (string)_provider.GetCacheItem("key", () => GetValue(3));
|
||||
value = (string)_provider.Get("key", () => GetValue(3));
|
||||
Assert.AreEqual("succ3", value);
|
||||
|
||||
// cache
|
||||
value = (string)_provider.GetCacheItem("key", () => GetValue(4));
|
||||
value = (string)_provider.Get("key", () => GetValue(4));
|
||||
Assert.AreEqual("succ3", value);
|
||||
}
|
||||
|
||||
|
||||
@@ -28,8 +28,8 @@ namespace Umbraco.Tests.Cache
|
||||
public void Caches_Single()
|
||||
{
|
||||
var isCached = false;
|
||||
var cache = new Mock<IRuntimeCacheProvider>();
|
||||
cache.Setup(x => x.InsertCacheItem(It.IsAny<string>(), It.IsAny<Func<object>>(), It.IsAny<TimeSpan?>(), It.IsAny<bool>(),
|
||||
var cache = new Mock<IAppPolicedCache>();
|
||||
cache.Setup(x => x.Insert(It.IsAny<string>(), It.IsAny<Func<object>>(), It.IsAny<TimeSpan?>(), It.IsAny<bool>(),
|
||||
It.IsAny<CacheItemPriority>(), It.IsAny<CacheItemRemovedCallback>(), It.IsAny<string[]>()))
|
||||
.Callback(() =>
|
||||
{
|
||||
@@ -45,8 +45,8 @@ namespace Umbraco.Tests.Cache
|
||||
[Test]
|
||||
public void Get_Single_From_Cache()
|
||||
{
|
||||
var cache = new Mock<IRuntimeCacheProvider>();
|
||||
cache.Setup(x => x.GetCacheItem(It.IsAny<string>())).Returns(new AuditItem(1, AuditType.Copy, 123, "test", "blah"));
|
||||
var cache = new Mock<IAppPolicedCache>();
|
||||
cache.Setup(x => x.Get(It.IsAny<string>())).Returns(new AuditItem(1, AuditType.Copy, 123, "test", "blah"));
|
||||
|
||||
var defaultPolicy = new DefaultRepositoryCachePolicy<AuditItem, object>(cache.Object, DefaultAccessor, new RepositoryCachePolicyOptions());
|
||||
|
||||
@@ -58,14 +58,14 @@ namespace Umbraco.Tests.Cache
|
||||
public void Caches_Per_Id_For_Get_All()
|
||||
{
|
||||
var cached = new List<string>();
|
||||
var cache = new Mock<IRuntimeCacheProvider>();
|
||||
cache.Setup(x => x.InsertCacheItem(It.IsAny<string>(), It.IsAny<Func<object>>(), It.IsAny<TimeSpan?>(), It.IsAny<bool>(),
|
||||
var cache = new Mock<IAppPolicedCache>();
|
||||
cache.Setup(x => x.Insert(It.IsAny<string>(), It.IsAny<Func<object>>(), It.IsAny<TimeSpan?>(), It.IsAny<bool>(),
|
||||
It.IsAny<CacheItemPriority>(), It.IsAny<CacheItemRemovedCallback>(), It.IsAny<string[]>()))
|
||||
.Callback((string cacheKey, Func<object> o, TimeSpan? t, bool b, CacheItemPriority cip, CacheItemRemovedCallback circ, string[] s) =>
|
||||
{
|
||||
cached.Add(cacheKey);
|
||||
});
|
||||
cache.Setup(x => x.GetCacheItemsByKeySearch(It.IsAny<string>())).Returns(new AuditItem[] {});
|
||||
cache.Setup(x => x.SearchByKey(It.IsAny<string>())).Returns(new AuditItem[] {});
|
||||
|
||||
var defaultPolicy = new DefaultRepositoryCachePolicy<AuditItem, object>(cache.Object, DefaultAccessor, new RepositoryCachePolicyOptions());
|
||||
|
||||
@@ -81,8 +81,8 @@ namespace Umbraco.Tests.Cache
|
||||
[Test]
|
||||
public void Get_All_Without_Ids_From_Cache()
|
||||
{
|
||||
var cache = new Mock<IRuntimeCacheProvider>();
|
||||
cache.Setup(x => x.GetCacheItemsByKeySearch(It.IsAny<string>())).Returns(new[]
|
||||
var cache = new Mock<IAppPolicedCache>();
|
||||
cache.Setup(x => x.SearchByKey(It.IsAny<string>())).Returns(new[]
|
||||
{
|
||||
new AuditItem(1, AuditType.Copy, 123, "test", "blah"),
|
||||
new AuditItem(2, AuditType.Copy, 123, "test", "blah2")
|
||||
@@ -98,8 +98,8 @@ namespace Umbraco.Tests.Cache
|
||||
public void If_CreateOrUpdate_Throws_Cache_Is_Removed()
|
||||
{
|
||||
var cacheCleared = false;
|
||||
var cache = new Mock<IRuntimeCacheProvider>();
|
||||
cache.Setup(x => x.ClearCacheItem(It.IsAny<string>()))
|
||||
var cache = new Mock<IAppPolicedCache>();
|
||||
cache.Setup(x => x.Clear(It.IsAny<string>()))
|
||||
.Callback(() =>
|
||||
{
|
||||
cacheCleared = true;
|
||||
@@ -124,8 +124,8 @@ namespace Umbraco.Tests.Cache
|
||||
public void If_Removes_Throws_Cache_Is_Removed()
|
||||
{
|
||||
var cacheCleared = false;
|
||||
var cache = new Mock<IRuntimeCacheProvider>();
|
||||
cache.Setup(x => x.ClearCacheItem(It.IsAny<string>()))
|
||||
var cache = new Mock<IAppPolicedCache>();
|
||||
cache.Setup(x => x.Clear(It.IsAny<string>()))
|
||||
.Callback(() =>
|
||||
{
|
||||
cacheCleared = true;
|
||||
|
||||
@@ -37,8 +37,8 @@ namespace Umbraco.Tests.Cache
|
||||
};
|
||||
|
||||
var isCached = false;
|
||||
var cache = new Mock<IRuntimeCacheProvider>();
|
||||
cache.Setup(x => x.InsertCacheItem(It.IsAny<string>(), It.IsAny<Func<object>>(), It.IsAny<TimeSpan?>(), It.IsAny<bool>(),
|
||||
var cache = new Mock<IAppPolicedCache>();
|
||||
cache.Setup(x => x.Insert(It.IsAny<string>(), It.IsAny<Func<object>>(), It.IsAny<TimeSpan?>(), It.IsAny<bool>(),
|
||||
It.IsAny<CacheItemPriority>(), It.IsAny<CacheItemRemovedCallback>(), It.IsAny<string[]>()))
|
||||
.Callback(() =>
|
||||
{
|
||||
@@ -60,8 +60,8 @@ namespace Umbraco.Tests.Cache
|
||||
new AuditItem(2, AuditType.Copy, 123, "test", "blah2")
|
||||
};
|
||||
|
||||
var cache = new Mock<IRuntimeCacheProvider>();
|
||||
cache.Setup(x => x.GetCacheItem(It.IsAny<string>())).Returns(new AuditItem(1, AuditType.Copy, 123, "test", "blah"));
|
||||
var cache = new Mock<IAppPolicedCache>();
|
||||
cache.Setup(x => x.Get(It.IsAny<string>())).Returns(new AuditItem(1, AuditType.Copy, 123, "test", "blah"));
|
||||
|
||||
var defaultPolicy = new FullDataSetRepositoryCachePolicy<AuditItem, object>(cache.Object, DefaultAccessor, item => item.Id, false);
|
||||
|
||||
@@ -78,8 +78,8 @@ namespace Umbraco.Tests.Cache
|
||||
|
||||
IList list = null;
|
||||
|
||||
var cache = new Mock<IRuntimeCacheProvider>();
|
||||
cache.Setup(x => x.InsertCacheItem(It.IsAny<string>(), It.IsAny<Func<object>>(), It.IsAny<TimeSpan?>(), It.IsAny<bool>(),
|
||||
var cache = new Mock<IAppPolicedCache>();
|
||||
cache.Setup(x => x.Insert(It.IsAny<string>(), It.IsAny<Func<object>>(), It.IsAny<TimeSpan?>(), It.IsAny<bool>(),
|
||||
It.IsAny<CacheItemPriority>(), It.IsAny<CacheItemRemovedCallback>(), It.IsAny<string[]>()))
|
||||
.Callback((string cacheKey, Func<object> o, TimeSpan? t, bool b, CacheItemPriority cip, CacheItemRemovedCallback circ, string[] s) =>
|
||||
{
|
||||
@@ -87,7 +87,7 @@ namespace Umbraco.Tests.Cache
|
||||
|
||||
list = o() as IList;
|
||||
});
|
||||
cache.Setup(x => x.GetCacheItem(It.IsAny<string>())).Returns(() =>
|
||||
cache.Setup(x => x.Get(It.IsAny<string>())).Returns(() =>
|
||||
{
|
||||
//return null if this is the first pass
|
||||
return cached.Any() ? new DeepCloneableList<AuditItem>(ListCloneBehavior.CloneOnce) : null;
|
||||
@@ -121,8 +121,8 @@ namespace Umbraco.Tests.Cache
|
||||
var cached = new List<string>();
|
||||
IList list = null;
|
||||
|
||||
var cache = new Mock<IRuntimeCacheProvider>();
|
||||
cache.Setup(x => x.InsertCacheItem(It.IsAny<string>(), It.IsAny<Func<object>>(), It.IsAny<TimeSpan?>(), It.IsAny<bool>(),
|
||||
var cache = new Mock<IAppPolicedCache>();
|
||||
cache.Setup(x => x.Insert(It.IsAny<string>(), It.IsAny<Func<object>>(), It.IsAny<TimeSpan?>(), It.IsAny<bool>(),
|
||||
It.IsAny<CacheItemPriority>(), It.IsAny<CacheItemRemovedCallback>(), It.IsAny<string[]>()))
|
||||
.Callback((string cacheKey, Func<object> o, TimeSpan? t, bool b, CacheItemPriority cip, CacheItemRemovedCallback circ, string[] s) =>
|
||||
{
|
||||
@@ -130,7 +130,7 @@ namespace Umbraco.Tests.Cache
|
||||
|
||||
list = o() as IList;
|
||||
});
|
||||
cache.Setup(x => x.GetCacheItem(It.IsAny<string>())).Returns(new AuditItem[] { });
|
||||
cache.Setup(x => x.Get(It.IsAny<string>())).Returns(new AuditItem[] { });
|
||||
|
||||
var defaultPolicy = new FullDataSetRepositoryCachePolicy<AuditItem, object>(cache.Object, DefaultAccessor, item => item.Id, false);
|
||||
|
||||
@@ -145,9 +145,9 @@ namespace Umbraco.Tests.Cache
|
||||
{
|
||||
var getAll = new[] { (AuditItem)null };
|
||||
|
||||
var cache = new Mock<IRuntimeCacheProvider>();
|
||||
var cache = new Mock<IAppPolicedCache>();
|
||||
|
||||
cache.Setup(x => x.GetCacheItem(It.IsAny<string>())).Returns(() => new DeepCloneableList<AuditItem>(ListCloneBehavior.CloneOnce)
|
||||
cache.Setup(x => x.Get(It.IsAny<string>())).Returns(() => new DeepCloneableList<AuditItem>(ListCloneBehavior.CloneOnce)
|
||||
{
|
||||
new AuditItem(1, AuditType.Copy, 123, "test", "blah"),
|
||||
new AuditItem(2, AuditType.Copy, 123, "test", "blah2")
|
||||
@@ -169,8 +169,8 @@ namespace Umbraco.Tests.Cache
|
||||
};
|
||||
|
||||
var cacheCleared = false;
|
||||
var cache = new Mock<IRuntimeCacheProvider>();
|
||||
cache.Setup(x => x.ClearCacheItem(It.IsAny<string>()))
|
||||
var cache = new Mock<IAppPolicedCache>();
|
||||
cache.Setup(x => x.Clear(It.IsAny<string>()))
|
||||
.Callback(() =>
|
||||
{
|
||||
cacheCleared = true;
|
||||
@@ -201,8 +201,8 @@ namespace Umbraco.Tests.Cache
|
||||
};
|
||||
|
||||
var cacheCleared = false;
|
||||
var cache = new Mock<IRuntimeCacheProvider>();
|
||||
cache.Setup(x => x.ClearCacheItem(It.IsAny<string>()))
|
||||
var cache = new Mock<IAppPolicedCache>();
|
||||
cache.Setup(x => x.Clear(It.IsAny<string>()))
|
||||
.Callback(() =>
|
||||
{
|
||||
cacheCleared = true;
|
||||
|
||||
@@ -7,17 +7,17 @@ namespace Umbraco.Tests.Cache
|
||||
[TestFixture]
|
||||
public class HttpRequestCacheProviderTests : CacheProviderTests
|
||||
{
|
||||
private HttpRequestCacheProvider _provider;
|
||||
private HttpRequestAppCache _provider;
|
||||
private FakeHttpContextFactory _ctx;
|
||||
|
||||
public override void Setup()
|
||||
{
|
||||
base.Setup();
|
||||
_ctx = new FakeHttpContextFactory("http://localhost/test");
|
||||
_provider = new HttpRequestCacheProvider(_ctx.HttpContext);
|
||||
_provider = new HttpRequestAppCache(_ctx.HttpContext);
|
||||
}
|
||||
|
||||
internal override ICacheProvider Provider
|
||||
internal override IAppCache Provider
|
||||
{
|
||||
get { return _provider; }
|
||||
}
|
||||
@@ -31,22 +31,22 @@ namespace Umbraco.Tests.Cache
|
||||
[TestFixture]
|
||||
public class StaticCacheProviderTests : CacheProviderTests
|
||||
{
|
||||
private StaticCacheProvider _provider;
|
||||
private DictionaryCacheProvider _provider;
|
||||
|
||||
public override void Setup()
|
||||
{
|
||||
base.Setup();
|
||||
_provider = new StaticCacheProvider();
|
||||
_provider = new DictionaryCacheProvider();
|
||||
}
|
||||
|
||||
internal override ICacheProvider Provider
|
||||
internal override IAppCache Provider
|
||||
{
|
||||
get { return _provider; }
|
||||
}
|
||||
|
||||
protected override int GetTotalItemCount
|
||||
{
|
||||
get { return _provider.StaticCache.Count; }
|
||||
get { return _provider.Items.Count; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Umbraco.Tests.Cache
|
||||
[TestFixture]
|
||||
public class HttpRuntimeCacheProviderTests : RuntimeCacheProviderTests
|
||||
{
|
||||
private HttpRuntimeCacheProvider _provider;
|
||||
private WebCachingAppCache _provider;
|
||||
|
||||
protected override int GetTotalItemCount
|
||||
{
|
||||
@@ -19,15 +19,15 @@ namespace Umbraco.Tests.Cache
|
||||
public override void Setup()
|
||||
{
|
||||
base.Setup();
|
||||
_provider = new HttpRuntimeCacheProvider(HttpRuntime.Cache);
|
||||
_provider = new WebCachingAppCache(HttpRuntime.Cache);
|
||||
}
|
||||
|
||||
internal override ICacheProvider Provider
|
||||
internal override IAppCache Provider
|
||||
{
|
||||
get { return _provider; }
|
||||
}
|
||||
|
||||
internal override IRuntimeCacheProvider RuntimeProvider
|
||||
internal override IAppPolicedCache RuntimeProvider
|
||||
{
|
||||
get { return _provider; }
|
||||
}
|
||||
@@ -36,15 +36,15 @@ namespace Umbraco.Tests.Cache
|
||||
public void DoesNotCacheExceptions()
|
||||
{
|
||||
string value;
|
||||
Assert.Throws<Exception>(() => { value = (string)_provider.GetCacheItem("key", () => GetValue(1)); });
|
||||
Assert.Throws<Exception>(() => { value = (string)_provider.GetCacheItem("key", () => GetValue(2)); });
|
||||
Assert.Throws<Exception>(() => { value = (string)_provider.Get("key", () => GetValue(1)); });
|
||||
Assert.Throws<Exception>(() => { value = (string)_provider.Get("key", () => GetValue(2)); });
|
||||
|
||||
// does not throw
|
||||
value = (string)_provider.GetCacheItem("key", () => GetValue(3));
|
||||
value = (string)_provider.Get("key", () => GetValue(3));
|
||||
Assert.AreEqual("succ3", value);
|
||||
|
||||
// cache
|
||||
value = (string)_provider.GetCacheItem("key", () => GetValue(4));
|
||||
value = (string)_provider.Get("key", () => GetValue(4));
|
||||
Assert.AreEqual("succ3", value);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace Umbraco.Tests.Cache
|
||||
[TestFixture]
|
||||
public class ObjectCacheProviderTests : RuntimeCacheProviderTests
|
||||
{
|
||||
private ObjectCacheRuntimeCacheProvider _provider;
|
||||
private ObjectCacheAppCache _provider;
|
||||
|
||||
protected override int GetTotalItemCount
|
||||
{
|
||||
@@ -20,15 +20,15 @@ namespace Umbraco.Tests.Cache
|
||||
public override void Setup()
|
||||
{
|
||||
base.Setup();
|
||||
_provider = new ObjectCacheRuntimeCacheProvider();
|
||||
_provider = new ObjectCacheAppCache();
|
||||
}
|
||||
|
||||
internal override ICacheProvider Provider
|
||||
internal override IAppCache Provider
|
||||
{
|
||||
get { return _provider; }
|
||||
}
|
||||
|
||||
internal override IRuntimeCacheProvider RuntimeProvider
|
||||
internal override IAppPolicedCache RuntimeProvider
|
||||
{
|
||||
get { return _provider; }
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace Umbraco.Tests.Cache.PublishedCache
|
||||
_xml = new XmlDocument();
|
||||
_xml.LoadXml(GetXml());
|
||||
var xmlStore = new XmlStore(() => _xml, null, null, null);
|
||||
var cacheProvider = new StaticCacheProvider();
|
||||
var cacheProvider = new DictionaryCacheProvider();
|
||||
var domainCache = new DomainCache(ServiceContext.DomainService, DefaultCultureAccessor);
|
||||
var publishedShapshot = new Umbraco.Web.PublishedCache.XmlPublishedCache.PublishedSnapshot(
|
||||
new PublishedContentCache(xmlStore, domainCache, cacheProvider, globalSettings, new SiteDomainHelper(), ContentTypesCache, null, null),
|
||||
|
||||
@@ -75,7 +75,7 @@ namespace Umbraco.Tests.Cache.PublishedCache
|
||||
var mChild2 = MakeNewMedia("Child2", mType, user, mRoot2.Id);
|
||||
|
||||
var ctx = GetUmbracoContext("/test");
|
||||
var cache = new PublishedMediaCache(new XmlStore((XmlDocument) null, null, null, null), ServiceContext.MediaService, ServiceContext.UserService, new StaticCacheProvider(), ContentTypesCache, Factory.GetInstance<IEntityXmlSerializer>());
|
||||
var cache = new PublishedMediaCache(new XmlStore((XmlDocument) null, null, null, null), ServiceContext.MediaService, ServiceContext.UserService, new DictionaryCacheProvider(), ContentTypesCache, Factory.GetInstance<IEntityXmlSerializer>());
|
||||
var roots = cache.GetAtRoot();
|
||||
Assert.AreEqual(2, roots.Count());
|
||||
Assert.IsTrue(roots.Select(x => x.Id).ContainsAll(new[] {mRoot1.Id, mRoot2.Id}));
|
||||
@@ -93,7 +93,7 @@ namespace Umbraco.Tests.Cache.PublishedCache
|
||||
|
||||
//var publishedMedia = PublishedMediaTests.GetNode(mRoot.Id, GetUmbracoContext("/test", 1234));
|
||||
var umbracoContext = GetUmbracoContext("/test");
|
||||
var cache = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null), Current.Services.MediaService, Current.Services.UserService, new StaticCacheProvider(), ContentTypesCache, Factory.GetInstance<IEntityXmlSerializer>());
|
||||
var cache = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null), Current.Services.MediaService, Current.Services.UserService, new DictionaryCacheProvider(), ContentTypesCache, Factory.GetInstance<IEntityXmlSerializer>());
|
||||
var publishedMedia = cache.GetById(mRoot.Id);
|
||||
Assert.IsNotNull(publishedMedia);
|
||||
|
||||
@@ -204,7 +204,7 @@ namespace Umbraco.Tests.Cache.PublishedCache
|
||||
|
||||
var result = new SearchResult("1234", 1, () => fields.ToDictionary(x => x.Key, x => new List<string> { x.Value }));
|
||||
|
||||
var store = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null), ServiceContext.MediaService, ServiceContext.UserService, new StaticCacheProvider(), ContentTypesCache, Factory.GetInstance<IEntityXmlSerializer>());
|
||||
var store = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null), ServiceContext.MediaService, ServiceContext.UserService, new DictionaryCacheProvider(), ContentTypesCache, Factory.GetInstance<IEntityXmlSerializer>());
|
||||
var doc = store.CreateFromCacheValues(store.ConvertFromSearchResult(result));
|
||||
|
||||
DoAssert(doc, 1234, key, templateIdVal: null, 0, "/media/test.jpg", "Image", 23, "Shannon", "Shannon", 0, 0, "-1,1234", DateTime.Parse("2012-07-17T10:34:09"), DateTime.Parse("2012-07-16T10:34:09"), 2);
|
||||
@@ -220,7 +220,7 @@ namespace Umbraco.Tests.Cache.PublishedCache
|
||||
var xmlDoc = GetMediaXml();
|
||||
((XmlElement)xmlDoc.DocumentElement.FirstChild).SetAttribute("key", key.ToString());
|
||||
var navigator = xmlDoc.SelectSingleNode("/root/Image").CreateNavigator();
|
||||
var cache = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null), ServiceContext.MediaService, ServiceContext.UserService, new StaticCacheProvider(), ContentTypesCache, Factory.GetInstance<IEntityXmlSerializer>());
|
||||
var cache = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null), ServiceContext.MediaService, ServiceContext.UserService, new DictionaryCacheProvider(), ContentTypesCache, Factory.GetInstance<IEntityXmlSerializer>());
|
||||
var doc = cache.CreateFromCacheValues(cache.ConvertFromXPathNavigator(navigator, true));
|
||||
|
||||
DoAssert(doc, 2000, key, templateIdVal: null, 2, "image1", "Image", 23, "Shannon", "Shannon", 33, 33, "-1,2000", DateTime.Parse("2012-06-12T14:13:17"), DateTime.Parse("2012-07-20T18:50:43"), 1);
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace Umbraco.Tests.Cache
|
||||
public abstract class RuntimeCacheProviderTests : CacheProviderTests
|
||||
{
|
||||
|
||||
internal abstract IRuntimeCacheProvider RuntimeProvider { get; }
|
||||
internal abstract IAppPolicedCache RuntimeProvider { get; }
|
||||
|
||||
|
||||
[Test]
|
||||
@@ -16,7 +16,7 @@ namespace Umbraco.Tests.Cache
|
||||
public void Can_Add_And_Expire_Struct_Strongly_Typed_With_Null()
|
||||
{
|
||||
var now = DateTime.Now;
|
||||
RuntimeProvider.InsertCacheItem("DateTimeTest", () => now, new TimeSpan(0, 0, 0, 0, 200));
|
||||
RuntimeProvider.Insert("DateTimeTest", () => now, new TimeSpan(0, 0, 0, 0, 200));
|
||||
Assert.AreEqual(now, Provider.GetCacheItem<DateTime>("DateTimeTest"));
|
||||
Assert.AreEqual(now, Provider.GetCacheItem<DateTime?>("DateTimeTest"));
|
||||
|
||||
|
||||
@@ -28,14 +28,14 @@ namespace Umbraco.Tests.Cache
|
||||
public void Get_All_Doesnt_Cache()
|
||||
{
|
||||
var cached = new List<string>();
|
||||
var cache = new Mock<IRuntimeCacheProvider>();
|
||||
cache.Setup(x => x.InsertCacheItem(It.IsAny<string>(), It.IsAny<Func<object>>(), It.IsAny<TimeSpan?>(), It.IsAny<bool>(),
|
||||
var cache = new Mock<IAppPolicedCache>();
|
||||
cache.Setup(x => x.Insert(It.IsAny<string>(), It.IsAny<Func<object>>(), It.IsAny<TimeSpan?>(), It.IsAny<bool>(),
|
||||
It.IsAny<CacheItemPriority>(), It.IsAny<CacheItemRemovedCallback>(), It.IsAny<string[]>()))
|
||||
.Callback((string cacheKey, Func<object> o, TimeSpan? t, bool b, CacheItemPriority cip, CacheItemRemovedCallback circ, string[] s) =>
|
||||
{
|
||||
cached.Add(cacheKey);
|
||||
});
|
||||
cache.Setup(x => x.GetCacheItemsByKeySearch(It.IsAny<string>())).Returns(new AuditItem[] { });
|
||||
cache.Setup(x => x.SearchByKey(It.IsAny<string>())).Returns(new AuditItem[] { });
|
||||
|
||||
var defaultPolicy = new SingleItemsOnlyRepositoryCachePolicy<AuditItem, object>(cache.Object, DefaultAccessor, new RepositoryCachePolicyOptions());
|
||||
|
||||
@@ -52,8 +52,8 @@ namespace Umbraco.Tests.Cache
|
||||
public void Caches_Single()
|
||||
{
|
||||
var isCached = false;
|
||||
var cache = new Mock<IRuntimeCacheProvider>();
|
||||
cache.Setup(x => x.InsertCacheItem(It.IsAny<string>(), It.IsAny<Func<object>>(), It.IsAny<TimeSpan?>(), It.IsAny<bool>(),
|
||||
var cache = new Mock<IAppPolicedCache>();
|
||||
cache.Setup(x => x.Insert(It.IsAny<string>(), It.IsAny<Func<object>>(), It.IsAny<TimeSpan?>(), It.IsAny<bool>(),
|
||||
It.IsAny<CacheItemPriority>(), It.IsAny<CacheItemRemovedCallback>(), It.IsAny<string[]>()))
|
||||
.Callback(() =>
|
||||
{
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace Umbraco.Tests.Composing
|
||||
{
|
||||
ProfilingLogger = new ProfilingLogger(Mock.Of<ILogger>(), Mock.Of<IProfiler>());
|
||||
|
||||
TypeLoader = new TypeLoader(NullCacheProvider.Instance, LocalTempStorage.Default, ProfilingLogger, detectChanges: false)
|
||||
TypeLoader = new TypeLoader(NoAppCache.Instance, LocalTempStorage.Default, ProfilingLogger, detectChanges: false)
|
||||
{
|
||||
AssembliesToScan = AssembliesToScan
|
||||
};
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace Umbraco.Tests.Composing
|
||||
public void Initialize()
|
||||
{
|
||||
// this ensures it's reset
|
||||
_typeLoader = new TypeLoader(NullCacheProvider.Instance, LocalTempStorage.Default, new ProfilingLogger(Mock.Of<ILogger>(), Mock.Of<IProfiler>()));
|
||||
_typeLoader = new TypeLoader(NoAppCache.Instance, LocalTempStorage.Default, new ProfilingLogger(Mock.Of<ILogger>(), Mock.Of<IProfiler>()));
|
||||
|
||||
foreach (var file in Directory.GetFiles(IOHelper.MapPath(SystemDirectories.TempData.EnsureEndsWith('/') + "TypesCache")))
|
||||
File.Delete(file);
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace Umbraco.Tests.CoreThings
|
||||
var container = new Mock<IFactory>();
|
||||
var globalSettings = SettingsForTests.GenerateMockGlobalSettings();
|
||||
container.Setup(x => x.GetInstance(typeof(TypeLoader))).Returns(
|
||||
new TypeLoader(NullCacheProvider.Instance, LocalTempStorage.Default, new ProfilingLogger(Mock.Of<ILogger>(), Mock.Of<IProfiler>())));
|
||||
new TypeLoader(NoAppCache.Instance, LocalTempStorage.Default, new ProfilingLogger(Mock.Of<ILogger>(), Mock.Of<IProfiler>())));
|
||||
Current.Factory = container.Object;
|
||||
|
||||
Udi.ResetUdiTypes();
|
||||
|
||||
@@ -413,7 +413,7 @@ namespace Umbraco.Tests.FrontEnd
|
||||
container
|
||||
.Setup(x => x.GetInstance(typeof(TypeLoader)))
|
||||
.Returns(new TypeLoader(
|
||||
NullCacheProvider.Instance,
|
||||
NoAppCache.Instance,
|
||||
LocalTempStorage.Default,
|
||||
new ProfilingLogger(Mock.Of<ILogger>(), Mock.Of<IProfiler>())
|
||||
)
|
||||
|
||||
@@ -22,10 +22,10 @@ namespace Umbraco.Tests.Macros
|
||||
{
|
||||
//we DO want cache enabled for these tests
|
||||
var cacheHelper = new AppCaches(
|
||||
new ObjectCacheRuntimeCacheProvider(),
|
||||
new StaticCacheProvider(),
|
||||
NullCacheProvider.Instance,
|
||||
new IsolatedRuntimeCache(type => new ObjectCacheRuntimeCacheProvider()));
|
||||
new ObjectCacheAppCache(),
|
||||
new DictionaryCacheProvider(),
|
||||
NoAppCache.Instance,
|
||||
new IsolatedCaches(type => new ObjectCacheAppCache()));
|
||||
//Current.ApplicationContext = new ApplicationContext(cacheHelper, new ProfilingLogger(Mock.Of<ILogger>(), Mock.Of<IProfiler>()));
|
||||
|
||||
Current.Reset();
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace Umbraco.Tests.Manifest
|
||||
new RequiredValidator(Mock.Of<ILocalizedTextService>()),
|
||||
new RegexValidator(Mock.Of<ILocalizedTextService>(), null)
|
||||
};
|
||||
_parser = new ManifestParser(NullCacheProvider.Instance, new ManifestValueValidatorCollection(validators), Mock.Of<ILogger>());
|
||||
_parser = new ManifestParser(NoAppCache.Instance, new ManifestValueValidatorCollection(validators), Mock.Of<ILogger>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -232,8 +232,8 @@ namespace Umbraco.Tests.Models
|
||||
content.UpdateDate = DateTime.Now;
|
||||
content.WriterId = 23;
|
||||
|
||||
var runtimeCache = new ObjectCacheRuntimeCacheProvider();
|
||||
runtimeCache.InsertCacheItem(content.Id.ToString(CultureInfo.InvariantCulture), () => content);
|
||||
var runtimeCache = new ObjectCacheAppCache();
|
||||
runtimeCache.Insert(content.Id.ToString(CultureInfo.InvariantCulture), () => content);
|
||||
|
||||
var proflog = GetTestProfilingLogger();
|
||||
|
||||
@@ -241,7 +241,7 @@ namespace Umbraco.Tests.Models
|
||||
{
|
||||
for (int j = 0; j < 1000; j++)
|
||||
{
|
||||
var clone = runtimeCache.GetCacheItem(content.Id.ToString(CultureInfo.InvariantCulture));
|
||||
var clone = runtimeCache.Get(content.Id.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -76,10 +76,10 @@ namespace Umbraco.Tests.Persistence.Repositories
|
||||
public void CacheActiveForIntsAndGuids()
|
||||
{
|
||||
var realCache = new AppCaches(
|
||||
new ObjectCacheRuntimeCacheProvider(),
|
||||
new StaticCacheProvider(),
|
||||
new StaticCacheProvider(),
|
||||
new IsolatedRuntimeCache(t => new ObjectCacheRuntimeCacheProvider()));
|
||||
new ObjectCacheAppCache(),
|
||||
new DictionaryCacheProvider(),
|
||||
new DictionaryCacheProvider(),
|
||||
new IsolatedCaches(t => new ObjectCacheAppCache()));
|
||||
|
||||
var provider = TestObjects.GetScopeProvider(Logger);
|
||||
using (var scope = provider.CreateScope())
|
||||
|
||||
@@ -47,10 +47,10 @@ namespace Umbraco.Tests.Persistence.Repositories
|
||||
MediaTypeRepository mediaTypeRepository;
|
||||
|
||||
var realCache = new AppCaches(
|
||||
new ObjectCacheRuntimeCacheProvider(),
|
||||
new StaticCacheProvider(),
|
||||
new StaticCacheProvider(),
|
||||
new IsolatedRuntimeCache(t => new ObjectCacheRuntimeCacheProvider()));
|
||||
new ObjectCacheAppCache(),
|
||||
new DictionaryCacheProvider(),
|
||||
new DictionaryCacheProvider(),
|
||||
new IsolatedCaches(t => new ObjectCacheAppCache()));
|
||||
|
||||
var provider = TestObjects.GetScopeProvider(Logger);
|
||||
using (var scope = provider.CreateScope())
|
||||
|
||||
@@ -118,8 +118,8 @@ namespace Umbraco.Tests.Published
|
||||
publishedContentTypeFactory.CreatePropertyType("prop1", 1),
|
||||
});
|
||||
|
||||
var elementsCache = new DictionaryCacheProvider();
|
||||
var snapshotCache = new DictionaryCacheProvider();
|
||||
var elementsCache = new FastDictionaryCacheProvider();
|
||||
var snapshotCache = new FastDictionaryCacheProvider();
|
||||
|
||||
var publishedSnapshot = new Mock<IPublishedSnapshot>();
|
||||
publishedSnapshot.Setup(x => x.SnapshotCache).Returns(snapshotCache);
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
Composition.RegisterUnique<IPublishedModelFactory>(f => new PublishedModelFactory(f.GetInstance<TypeLoader>().GetTypes<PublishedContentModel>()));
|
||||
}
|
||||
|
||||
protected override TypeLoader CreateTypeLoader(IRuntimeCacheProvider runtimeCache, IGlobalSettings globalSettings, IProfilingLogger logger)
|
||||
protected override TypeLoader CreateTypeLoader(IAppPolicedCache runtimeCache, IGlobalSettings globalSettings, IProfilingLogger logger)
|
||||
{
|
||||
var pluginManager = base.CreateTypeLoader(runtimeCache, globalSettings, logger);
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
ContentTypesCache.GetPublishedContentTypeByAlias = alias => alias.InvariantEquals("home") ? homeType : anythingType;
|
||||
}
|
||||
|
||||
protected override TypeLoader CreateTypeLoader(IRuntimeCacheProvider runtimeCache, IGlobalSettings globalSettings, IProfilingLogger logger)
|
||||
protected override TypeLoader CreateTypeLoader(IAppPolicedCache runtimeCache, IGlobalSettings globalSettings, IProfilingLogger logger)
|
||||
{
|
||||
var pluginManager = base.CreateTypeLoader(runtimeCache, globalSettings, logger);
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
internal IPublishedContent GetNode(int id, UmbracoContext umbracoContext)
|
||||
{
|
||||
var cache = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null),
|
||||
ServiceContext.MediaService, ServiceContext.UserService, new StaticCacheProvider(), ContentTypesCache,
|
||||
ServiceContext.MediaService, ServiceContext.UserService, new DictionaryCacheProvider(), ContentTypesCache,
|
||||
Factory.GetInstance<IEntityXmlSerializer>());
|
||||
var doc = cache.GetById(id);
|
||||
Assert.IsNotNull(doc);
|
||||
@@ -126,7 +126,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
|
||||
var searcher = indexer.GetSearcher();
|
||||
var ctx = GetUmbracoContext("/test");
|
||||
var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, new StaticCacheProvider(), ContentTypesCache, Factory.GetInstance<IEntityXmlSerializer>());
|
||||
var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, new DictionaryCacheProvider(), ContentTypesCache, Factory.GetInstance<IEntityXmlSerializer>());
|
||||
|
||||
//we are using the media.xml media to test the examine results implementation, see the media.xml file in the ExamineHelpers namespace
|
||||
var publishedMedia = cache.GetById(1111);
|
||||
@@ -156,7 +156,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
|
||||
var searcher = indexer.GetSearcher();
|
||||
var ctx = GetUmbracoContext("/test");
|
||||
var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, new StaticCacheProvider(), ContentTypesCache, Factory.GetInstance<IEntityXmlSerializer>());
|
||||
var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, new DictionaryCacheProvider(), ContentTypesCache, Factory.GetInstance<IEntityXmlSerializer>());
|
||||
|
||||
//ensure it is found
|
||||
var publishedMedia = cache.GetById(3113);
|
||||
@@ -203,7 +203,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
|
||||
var searcher = indexer.GetSearcher();
|
||||
var ctx = GetUmbracoContext("/test");
|
||||
var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, new StaticCacheProvider(), ContentTypesCache, Factory.GetInstance<IEntityXmlSerializer>());
|
||||
var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, new DictionaryCacheProvider(), ContentTypesCache, Factory.GetInstance<IEntityXmlSerializer>());
|
||||
|
||||
//we are using the media.xml media to test the examine results implementation, see the media.xml file in the ExamineHelpers namespace
|
||||
var publishedMedia = cache.GetById(1111);
|
||||
@@ -231,7 +231,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
|
||||
var searcher = indexer.GetSearcher();
|
||||
var ctx = GetUmbracoContext("/test");
|
||||
var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, new StaticCacheProvider(), ContentTypesCache, Factory.GetInstance<IEntityXmlSerializer>());
|
||||
var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, new DictionaryCacheProvider(), ContentTypesCache, Factory.GetInstance<IEntityXmlSerializer>());
|
||||
|
||||
//we are using the media.xml media to test the examine results implementation, see the media.xml file in the ExamineHelpers namespace
|
||||
var publishedMedia = cache.GetById(1111);
|
||||
@@ -259,7 +259,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
|
||||
var searcher = indexer.GetSearcher();
|
||||
var ctx = GetUmbracoContext("/test");
|
||||
var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, new StaticCacheProvider(), ContentTypesCache, Factory.GetInstance<IEntityXmlSerializer>());
|
||||
var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, new DictionaryCacheProvider(), ContentTypesCache, Factory.GetInstance<IEntityXmlSerializer>());
|
||||
|
||||
//we are using the media.xml media to test the examine results implementation, see the media.xml file in the ExamineHelpers namespace
|
||||
var publishedMedia = cache.GetById(1111);
|
||||
@@ -288,7 +288,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
|
||||
var ctx = GetUmbracoContext("/test");
|
||||
var searcher = indexer.GetSearcher();
|
||||
var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, new StaticCacheProvider(), ContentTypesCache, Factory.GetInstance<IEntityXmlSerializer>());
|
||||
var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, new DictionaryCacheProvider(), ContentTypesCache, Factory.GetInstance<IEntityXmlSerializer>());
|
||||
|
||||
//we are using the media.xml media to test the examine results implementation, see the media.xml file in the ExamineHelpers namespace
|
||||
var publishedMedia = cache.GetById(3113);
|
||||
@@ -314,7 +314,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
|
||||
var ctx = GetUmbracoContext("/test");
|
||||
var searcher = indexer.GetSearcher();
|
||||
var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, new StaticCacheProvider(), ContentTypesCache, Factory.GetInstance<IEntityXmlSerializer>());
|
||||
var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, new DictionaryCacheProvider(), ContentTypesCache, Factory.GetInstance<IEntityXmlSerializer>());
|
||||
|
||||
//we are using the media.xml media to test the examine results implementation, see the media.xml file in the ExamineHelpers namespace
|
||||
var publishedMedia = cache.GetById(3113);
|
||||
@@ -482,7 +482,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
</Image>");
|
||||
var node = xml.DescendantsAndSelf("Image").Single(x => (int)x.Attribute("id") == nodeId);
|
||||
|
||||
var publishedMedia = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null), ServiceContext.MediaService, ServiceContext.UserService, new StaticCacheProvider(), ContentTypesCache, Factory.GetInstance<IEntityXmlSerializer>());
|
||||
var publishedMedia = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null), ServiceContext.MediaService, ServiceContext.UserService, new DictionaryCacheProvider(), ContentTypesCache, Factory.GetInstance<IEntityXmlSerializer>());
|
||||
|
||||
var nav = node.CreateNavigator();
|
||||
|
||||
@@ -502,7 +502,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
var errorXml = new XElement("error", string.Format("No media is maching '{0}'", 1234));
|
||||
var nav = errorXml.CreateNavigator();
|
||||
|
||||
var publishedMedia = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null), ServiceContext.MediaService, ServiceContext.UserService, new StaticCacheProvider(), ContentTypesCache, Factory.GetInstance<IEntityXmlSerializer>());
|
||||
var publishedMedia = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null), ServiceContext.MediaService, ServiceContext.UserService, new DictionaryCacheProvider(), ContentTypesCache, Factory.GetInstance<IEntityXmlSerializer>());
|
||||
var converted = publishedMedia.ConvertFromXPathNodeIterator(nav.Select("/"), 1234);
|
||||
|
||||
Assert.IsNull(converted);
|
||||
|
||||
@@ -36,9 +36,9 @@ namespace Umbraco.Tests.PublishedContent
|
||||
public void Resync()
|
||||
{ }
|
||||
|
||||
public ICacheProvider SnapshotCache => null;
|
||||
public IAppCache SnapshotCache => null;
|
||||
|
||||
public ICacheProvider ElementsCache => null;
|
||||
public IAppCache ElementsCache => null;
|
||||
}
|
||||
|
||||
class SolidPublishedContentCache : PublishedCacheBase, IPublishedContentCache, IPublishedMediaCache
|
||||
|
||||
@@ -41,10 +41,10 @@ namespace Umbraco.Tests.Scoping
|
||||
{
|
||||
// this is what's created core web runtime
|
||||
return new AppCaches(
|
||||
new DeepCloneRuntimeCacheProvider(new ObjectCacheRuntimeCacheProvider()),
|
||||
new StaticCacheProvider(),
|
||||
NullCacheProvider.Instance,
|
||||
new IsolatedRuntimeCache(type => new DeepCloneRuntimeCacheProvider(new ObjectCacheRuntimeCacheProvider())));
|
||||
new DeepCloneAppCache(new ObjectCacheAppCache()),
|
||||
new DictionaryCacheProvider(),
|
||||
NoAppCache.Instance,
|
||||
new IsolatedCaches(type => new DeepCloneAppCache(new ObjectCacheAppCache())));
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
@@ -60,13 +60,13 @@ namespace Umbraco.Tests.Scoping
|
||||
{
|
||||
var scopeProvider = ScopeProvider;
|
||||
var service = Current.Services.UserService;
|
||||
var globalCache = Current.ApplicationCache.IsolatedRuntimeCache.GetOrCreateCache(typeof(IUser));
|
||||
var globalCache = Current.ApplicationCache.IsolatedCaches.GetOrCreate(typeof(IUser));
|
||||
|
||||
var user = (IUser)new User("name", "email", "username", "rawPassword");
|
||||
service.Save(user);
|
||||
|
||||
// global cache contains the entity
|
||||
var globalCached = (IUser) globalCache.GetCacheItem(GetCacheIdKey<IUser>(user.Id), () => null);
|
||||
var globalCached = (IUser) globalCache.Get(GetCacheIdKey<IUser>(user.Id), () => null);
|
||||
Assert.IsNotNull(globalCached);
|
||||
Assert.AreEqual(user.Id, globalCached.Id);
|
||||
Assert.AreEqual("name", globalCached.Name);
|
||||
@@ -85,20 +85,20 @@ namespace Umbraco.Tests.Scoping
|
||||
Assert.AreSame(scope, scopeProvider.AmbientScope);
|
||||
|
||||
// scope has its own isolated cache
|
||||
var scopedCache = scope.IsolatedRuntimeCache.GetOrCreateCache(typeof (IUser));
|
||||
var scopedCache = scope.IsolatedCaches.GetOrCreate(typeof (IUser));
|
||||
Assert.AreNotSame(globalCache, scopedCache);
|
||||
|
||||
user.Name = "changed";
|
||||
service.Save(user);
|
||||
|
||||
// scoped cache contains the "new" entity
|
||||
var scopeCached = (IUser) scopedCache.GetCacheItem(GetCacheIdKey<IUser>(user.Id), () => null);
|
||||
var scopeCached = (IUser) scopedCache.Get(GetCacheIdKey<IUser>(user.Id), () => null);
|
||||
Assert.IsNotNull(scopeCached);
|
||||
Assert.AreEqual(user.Id, scopeCached.Id);
|
||||
Assert.AreEqual("changed", scopeCached.Name);
|
||||
|
||||
// global cache is unchanged
|
||||
globalCached = (IUser) globalCache.GetCacheItem(GetCacheIdKey<IUser>(user.Id), () => null);
|
||||
globalCached = (IUser) globalCache.Get(GetCacheIdKey<IUser>(user.Id), () => null);
|
||||
Assert.IsNotNull(globalCached);
|
||||
Assert.AreEqual(user.Id, globalCached.Id);
|
||||
Assert.AreEqual("name", globalCached.Name);
|
||||
@@ -108,7 +108,7 @@ namespace Umbraco.Tests.Scoping
|
||||
}
|
||||
Assert.IsNull(scopeProvider.AmbientScope);
|
||||
|
||||
globalCached = (IUser) globalCache.GetCacheItem(GetCacheIdKey<IUser>(user.Id), () => null);
|
||||
globalCached = (IUser) globalCache.Get(GetCacheIdKey<IUser>(user.Id), () => null);
|
||||
if (complete)
|
||||
{
|
||||
// global cache has been cleared
|
||||
@@ -125,7 +125,7 @@ namespace Umbraco.Tests.Scoping
|
||||
Assert.AreEqual(complete ? "changed" : "name", user.Name);
|
||||
|
||||
// global cache contains the entity again
|
||||
globalCached = (IUser) globalCache.GetCacheItem(GetCacheIdKey<IUser>(user.Id), () => null);
|
||||
globalCached = (IUser) globalCache.Get(GetCacheIdKey<IUser>(user.Id), () => null);
|
||||
Assert.IsNotNull(globalCached);
|
||||
Assert.AreEqual(user.Id, globalCached.Id);
|
||||
Assert.AreEqual(complete ? "changed" : "name", globalCached.Name);
|
||||
@@ -137,18 +137,18 @@ namespace Umbraco.Tests.Scoping
|
||||
{
|
||||
var scopeProvider = ScopeProvider;
|
||||
var service = Current.Services.LocalizationService;
|
||||
var globalCache = Current.ApplicationCache.IsolatedRuntimeCache.GetOrCreateCache(typeof (ILanguage));
|
||||
var globalCache = Current.ApplicationCache.IsolatedCaches.GetOrCreate(typeof (ILanguage));
|
||||
|
||||
var lang = (ILanguage) new Language("fr-FR");
|
||||
service.Save(lang);
|
||||
|
||||
// global cache has been flushed, reload
|
||||
var globalFullCached = (IEnumerable<ILanguage>) globalCache.GetCacheItem(GetCacheTypeKey<ILanguage>(), () => null);
|
||||
var globalFullCached = (IEnumerable<ILanguage>) globalCache.Get(GetCacheTypeKey<ILanguage>(), () => null);
|
||||
Assert.IsNull(globalFullCached);
|
||||
var reload = service.GetLanguageById(lang.Id);
|
||||
|
||||
// global cache contains the entity
|
||||
globalFullCached = (IEnumerable<ILanguage>) globalCache.GetCacheItem(GetCacheTypeKey<ILanguage>(), () => null);
|
||||
globalFullCached = (IEnumerable<ILanguage>) globalCache.Get(GetCacheTypeKey<ILanguage>(), () => null);
|
||||
Assert.IsNotNull(globalFullCached);
|
||||
var globalCached = globalFullCached.First(x => x.Id == lang.Id);
|
||||
Assert.IsNotNull(globalCached);
|
||||
@@ -166,19 +166,19 @@ namespace Umbraco.Tests.Scoping
|
||||
Assert.AreSame(scope, scopeProvider.AmbientScope);
|
||||
|
||||
// scope has its own isolated cache
|
||||
var scopedCache = scope.IsolatedRuntimeCache.GetOrCreateCache(typeof (ILanguage));
|
||||
var scopedCache = scope.IsolatedCaches.GetOrCreate(typeof (ILanguage));
|
||||
Assert.AreNotSame(globalCache, scopedCache);
|
||||
|
||||
lang.IsoCode = "de-DE";
|
||||
service.Save(lang);
|
||||
|
||||
// scoped cache has been flushed, reload
|
||||
var scopeFullCached = (IEnumerable<ILanguage>) scopedCache.GetCacheItem(GetCacheTypeKey<ILanguage>(), () => null);
|
||||
var scopeFullCached = (IEnumerable<ILanguage>) scopedCache.Get(GetCacheTypeKey<ILanguage>(), () => null);
|
||||
Assert.IsNull(scopeFullCached);
|
||||
reload = service.GetLanguageById(lang.Id);
|
||||
|
||||
// scoped cache contains the "new" entity
|
||||
scopeFullCached = (IEnumerable<ILanguage>) scopedCache.GetCacheItem(GetCacheTypeKey<ILanguage>(), () => null);
|
||||
scopeFullCached = (IEnumerable<ILanguage>) scopedCache.Get(GetCacheTypeKey<ILanguage>(), () => null);
|
||||
Assert.IsNotNull(scopeFullCached);
|
||||
var scopeCached = scopeFullCached.First(x => x.Id == lang.Id);
|
||||
Assert.IsNotNull(scopeCached);
|
||||
@@ -186,7 +186,7 @@ namespace Umbraco.Tests.Scoping
|
||||
Assert.AreEqual("de-DE", scopeCached.IsoCode);
|
||||
|
||||
// global cache is unchanged
|
||||
globalFullCached = (IEnumerable<ILanguage>) globalCache.GetCacheItem(GetCacheTypeKey<ILanguage>(), () => null);
|
||||
globalFullCached = (IEnumerable<ILanguage>) globalCache.Get(GetCacheTypeKey<ILanguage>(), () => null);
|
||||
Assert.IsNotNull(globalFullCached);
|
||||
globalCached = globalFullCached.First(x => x.Id == lang.Id);
|
||||
Assert.IsNotNull(globalCached);
|
||||
@@ -198,7 +198,7 @@ namespace Umbraco.Tests.Scoping
|
||||
}
|
||||
Assert.IsNull(scopeProvider.AmbientScope);
|
||||
|
||||
globalFullCached = (IEnumerable<ILanguage>) globalCache.GetCacheItem(GetCacheTypeKey<ILanguage>(), () => null);
|
||||
globalFullCached = (IEnumerable<ILanguage>) globalCache.Get(GetCacheTypeKey<ILanguage>(), () => null);
|
||||
if (complete)
|
||||
{
|
||||
// global cache has been cleared
|
||||
@@ -215,7 +215,7 @@ namespace Umbraco.Tests.Scoping
|
||||
Assert.AreEqual(complete ? "de-DE" : "fr-FR", lang.IsoCode);
|
||||
|
||||
// global cache contains the entity again
|
||||
globalFullCached = (IEnumerable<ILanguage>) globalCache.GetCacheItem(GetCacheTypeKey<ILanguage>(), () => null);
|
||||
globalFullCached = (IEnumerable<ILanguage>) globalCache.Get(GetCacheTypeKey<ILanguage>(), () => null);
|
||||
Assert.IsNotNull(globalFullCached);
|
||||
globalCached = globalFullCached.First(x => x.Id == lang.Id);
|
||||
Assert.IsNotNull(globalCached);
|
||||
@@ -229,7 +229,7 @@ namespace Umbraco.Tests.Scoping
|
||||
{
|
||||
var scopeProvider = ScopeProvider;
|
||||
var service = Current.Services.LocalizationService;
|
||||
var globalCache = Current.ApplicationCache.IsolatedRuntimeCache.GetOrCreateCache(typeof (IDictionaryItem));
|
||||
var globalCache = Current.ApplicationCache.IsolatedCaches.GetOrCreate(typeof (IDictionaryItem));
|
||||
|
||||
var lang = (ILanguage)new Language("fr-FR");
|
||||
service.Save(lang);
|
||||
@@ -242,7 +242,7 @@ namespace Umbraco.Tests.Scoping
|
||||
service.Save(item);
|
||||
|
||||
// global cache contains the entity
|
||||
var globalCached = (IDictionaryItem) globalCache.GetCacheItem(GetCacheIdKey<IDictionaryItem>(item.Id), () => null);
|
||||
var globalCached = (IDictionaryItem) globalCache.Get(GetCacheIdKey<IDictionaryItem>(item.Id), () => null);
|
||||
Assert.IsNotNull(globalCached);
|
||||
Assert.AreEqual(item.Id, globalCached.Id);
|
||||
Assert.AreEqual("item-key", globalCached.ItemKey);
|
||||
@@ -258,20 +258,20 @@ namespace Umbraco.Tests.Scoping
|
||||
Assert.AreSame(scope, scopeProvider.AmbientScope);
|
||||
|
||||
// scope has its own isolated cache
|
||||
var scopedCache = scope.IsolatedRuntimeCache.GetOrCreateCache(typeof (IDictionaryItem));
|
||||
var scopedCache = scope.IsolatedCaches.GetOrCreate(typeof (IDictionaryItem));
|
||||
Assert.AreNotSame(globalCache, scopedCache);
|
||||
|
||||
item.ItemKey = "item-changed";
|
||||
service.Save(item);
|
||||
|
||||
// scoped cache contains the "new" entity
|
||||
var scopeCached = (IDictionaryItem) scopedCache.GetCacheItem(GetCacheIdKey<IDictionaryItem>(item.Id), () => null);
|
||||
var scopeCached = (IDictionaryItem) scopedCache.Get(GetCacheIdKey<IDictionaryItem>(item.Id), () => null);
|
||||
Assert.IsNotNull(scopeCached);
|
||||
Assert.AreEqual(item.Id, scopeCached.Id);
|
||||
Assert.AreEqual("item-changed", scopeCached.ItemKey);
|
||||
|
||||
// global cache is unchanged
|
||||
globalCached = (IDictionaryItem) globalCache.GetCacheItem(GetCacheIdKey<IDictionaryItem>(item.Id), () => null);
|
||||
globalCached = (IDictionaryItem) globalCache.Get(GetCacheIdKey<IDictionaryItem>(item.Id), () => null);
|
||||
Assert.IsNotNull(globalCached);
|
||||
Assert.AreEqual(item.Id, globalCached.Id);
|
||||
Assert.AreEqual("item-key", globalCached.ItemKey);
|
||||
@@ -281,7 +281,7 @@ namespace Umbraco.Tests.Scoping
|
||||
}
|
||||
Assert.IsNull(scopeProvider.AmbientScope);
|
||||
|
||||
globalCached = (IDictionaryItem) globalCache.GetCacheItem(GetCacheIdKey<IDictionaryItem>(item.Id), () => null);
|
||||
globalCached = (IDictionaryItem) globalCache.Get(GetCacheIdKey<IDictionaryItem>(item.Id), () => null);
|
||||
if (complete)
|
||||
{
|
||||
// global cache has been cleared
|
||||
@@ -298,7 +298,7 @@ namespace Umbraco.Tests.Scoping
|
||||
Assert.AreEqual(complete ? "item-changed" : "item-key", item.ItemKey);
|
||||
|
||||
// global cache contains the entity again
|
||||
globalCached = (IDictionaryItem) globalCache.GetCacheItem(GetCacheIdKey<IDictionaryItem>(item.Id), () => null);
|
||||
globalCached = (IDictionaryItem) globalCache.Get(GetCacheIdKey<IDictionaryItem>(item.Id), () => null);
|
||||
Assert.IsNotNull(globalCached);
|
||||
Assert.AreEqual(item.Id, globalCached.Id);
|
||||
Assert.AreEqual(complete ? "item-changed" : "item-key", globalCached.ItemKey);
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace Umbraco.Tests.TestHelpers
|
||||
var container = RegisterFactory.Create();
|
||||
|
||||
var logger = new ProfilingLogger(Mock.Of<ILogger>(), Mock.Of<IProfiler>());
|
||||
var typeLoader = new TypeLoader(NullCacheProvider.Instance,
|
||||
var typeLoader = new TypeLoader(NoAppCache.Instance,
|
||||
LocalTempStorage.Default,
|
||||
logger,
|
||||
false);
|
||||
|
||||
@@ -246,7 +246,7 @@ namespace Umbraco.Tests.TestHelpers
|
||||
|
||||
protected virtual IPublishedSnapshotService CreatePublishedSnapshotService()
|
||||
{
|
||||
var cache = NullCacheProvider.Instance;
|
||||
var cache = NoAppCache.Instance;
|
||||
|
||||
ContentTypesCache = new PublishedContentTypeCache(
|
||||
Factory.GetInstance<IContentTypeService>(),
|
||||
|
||||
@@ -245,7 +245,7 @@ namespace Umbraco.Tests.Testing
|
||||
.ComposeWebMappingProfiles();
|
||||
}
|
||||
|
||||
protected virtual TypeLoader GetTypeLoader(IRuntimeCacheProvider runtimeCache, IGlobalSettings globalSettings, IProfilingLogger logger, UmbracoTestOptions.TypeLoader option)
|
||||
protected virtual TypeLoader GetTypeLoader(IAppPolicedCache runtimeCache, IGlobalSettings globalSettings, IProfilingLogger logger, UmbracoTestOptions.TypeLoader option)
|
||||
{
|
||||
switch (option)
|
||||
{
|
||||
@@ -260,13 +260,13 @@ namespace Umbraco.Tests.Testing
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual TypeLoader CreateTypeLoader(IRuntimeCacheProvider runtimeCache, IGlobalSettings globalSettings, IProfilingLogger logger)
|
||||
protected virtual TypeLoader CreateTypeLoader(IAppPolicedCache runtimeCache, IGlobalSettings globalSettings, IProfilingLogger logger)
|
||||
{
|
||||
return CreateCommonTypeLoader(runtimeCache, globalSettings, logger);
|
||||
}
|
||||
|
||||
// common to all tests = cannot be overriden
|
||||
private static TypeLoader CreateCommonTypeLoader(IRuntimeCacheProvider runtimeCache, IGlobalSettings globalSettings, IProfilingLogger logger)
|
||||
private static TypeLoader CreateCommonTypeLoader(IAppPolicedCache runtimeCache, IGlobalSettings globalSettings, IProfilingLogger logger)
|
||||
{
|
||||
return new TypeLoader(runtimeCache, globalSettings.LocalTempStorageLocation, logger, false)
|
||||
{
|
||||
|
||||
@@ -415,7 +415,7 @@ namespace Umbraco.Tests.Web.Mvc
|
||||
// CacheHelper.CreateDisabledCacheHelper(),
|
||||
// new ProfilingLogger(logger, Mock.Of<IProfiler>())) { /*IsReady = true*/ };
|
||||
|
||||
var cache = NullCacheProvider.Instance;
|
||||
var cache = NoAppCache.Instance;
|
||||
//var provider = new ScopeUnitOfWorkProvider(databaseFactory, new RepositoryFactory(Mock.Of<IServiceContainer>()));
|
||||
var scopeProvider = TestObjects.GetScopeProvider(Mock.Of<ILogger>());
|
||||
var factory = Mock.Of<IPublishedContentTypeFactory>();
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace Umbraco.Tests.Web
|
||||
// fixme - bad in a unit test - but Udi has a static ctor that wants it?!
|
||||
var factory = new Mock<IFactory>();
|
||||
factory.Setup(x => x.GetInstance(typeof(TypeLoader))).Returns(
|
||||
new TypeLoader(NullCacheProvider.Instance, LocalTempStorage.Default, new ProfilingLogger(Mock.Of<ILogger>(), Mock.Of<IProfiler>())));
|
||||
new TypeLoader(NoAppCache.Instance, LocalTempStorage.Default, new ProfilingLogger(Mock.Of<ILogger>(), Mock.Of<IProfiler>())));
|
||||
factory.Setup(x => x.GetInstance(typeof (ServiceContext))).Returns(serviceContext);
|
||||
|
||||
var settings = SettingsForTests.GetDefaultUmbracoSettings();
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace Umbraco.Web.Cache
|
||||
|
||||
public override void RefreshAll()
|
||||
{
|
||||
AppCaches.RuntimeCache.ClearCacheItem(CacheKeys.ApplicationsCacheKey);
|
||||
AppCaches.RuntimeCache.Clear(CacheKeys.ApplicationsCacheKey);
|
||||
base.RefreshAll();
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace Umbraco.Web.Cache
|
||||
|
||||
public override void Remove(int id)
|
||||
{
|
||||
AppCaches.RuntimeCache.ClearCacheItem(CacheKeys.ApplicationsCacheKey);
|
||||
AppCaches.RuntimeCache.Clear(CacheKeys.ApplicationsCacheKey);
|
||||
base.Remove(id);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace Umbraco.Web.Cache
|
||||
|
||||
public override void RefreshAll()
|
||||
{
|
||||
AppCaches.RuntimeCache.ClearCacheItem(CacheKeys.ApplicationTreeCacheKey);
|
||||
AppCaches.RuntimeCache.Clear(CacheKeys.ApplicationTreeCacheKey);
|
||||
base.RefreshAll();
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace Umbraco.Web.Cache
|
||||
|
||||
public override void Remove(int id)
|
||||
{
|
||||
AppCaches.RuntimeCache.ClearCacheItem(CacheKeys.ApplicationTreeCacheKey);
|
||||
AppCaches.RuntimeCache.Clear(CacheKeys.ApplicationTreeCacheKey);
|
||||
base.Remove(id);
|
||||
}
|
||||
|
||||
|
||||
@@ -44,14 +44,14 @@ namespace Umbraco.Web.Cache
|
||||
|
||||
public override void Refresh(JsonPayload[] payloads)
|
||||
{
|
||||
AppCaches.RuntimeCache.ClearCacheObjectTypes<PublicAccessEntry>();
|
||||
AppCaches.RuntimeCache.ClearOfType<PublicAccessEntry>();
|
||||
|
||||
var idsRemoved = new HashSet<int>();
|
||||
var isolatedCache = AppCaches.IsolatedRuntimeCache.GetOrCreateCache<IContent>();
|
||||
var isolatedCache = AppCaches.IsolatedCaches.GetOrCreate<IContent>();
|
||||
|
||||
foreach (var payload in payloads)
|
||||
{
|
||||
isolatedCache.ClearCacheItem(RepositoryCacheKeys.GetKey<IContent>(payload.Id));
|
||||
isolatedCache.Clear(RepositoryCacheKeys.GetKey<IContent>(payload.Id));
|
||||
|
||||
_idkMap.ClearCache(payload.Id);
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace Umbraco.Web.Cache
|
||||
if (payload.ChangeTypes.HasTypesAny(TreeChangeTypes.RefreshBranch | TreeChangeTypes.Remove))
|
||||
{
|
||||
var pathid = "," + payload.Id + ",";
|
||||
isolatedCache.ClearCacheObjectTypes<IContent>((k, v) => v.Path.Contains(pathid));
|
||||
isolatedCache.ClearOfType<IContent>((k, v) => v.Path.Contains(pathid));
|
||||
}
|
||||
|
||||
//if the item is being completely removed, we need to refresh the domains cache if any domain was assigned to the content
|
||||
@@ -162,8 +162,8 @@ namespace Umbraco.Web.Cache
|
||||
appCaches.ClearPartialViewCache();
|
||||
MacroCacheRefresher.ClearMacroContentCache(appCaches); // just the content
|
||||
|
||||
appCaches.IsolatedRuntimeCache.ClearCache<PublicAccessEntry>();
|
||||
appCaches.IsolatedRuntimeCache.ClearCache<IContent>();
|
||||
appCaches.IsolatedCaches.ClearCache<PublicAccessEntry>();
|
||||
appCaches.IsolatedCaches.ClearCache<IContent>();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace Umbraco.Web.Cache
|
||||
ClearAllIsolatedCacheByEntityType<IMember>();
|
||||
ClearAllIsolatedCacheByEntityType<IMemberType>();
|
||||
|
||||
var dataTypeCache = AppCaches.IsolatedRuntimeCache.GetCache<IDataType>();
|
||||
var dataTypeCache = AppCaches.IsolatedCaches.Get<IDataType>();
|
||||
|
||||
foreach (var payload in payloads)
|
||||
{
|
||||
|
||||
@@ -33,11 +33,11 @@ namespace Umbraco.Web.Cache
|
||||
public override void RefreshAll()
|
||||
{
|
||||
foreach (var prefix in GetAllMacroCacheKeys())
|
||||
AppCaches.RuntimeCache.ClearCacheByKeySearch(prefix);
|
||||
AppCaches.RuntimeCache.ClearByKey(prefix);
|
||||
|
||||
ClearAllIsolatedCacheByEntityType<IMacro>();
|
||||
|
||||
AppCaches.RuntimeCache.ClearCacheObjectTypes<MacroCacheContent>();
|
||||
AppCaches.RuntimeCache.ClearOfType<MacroCacheContent>();
|
||||
|
||||
base.RefreshAll();
|
||||
}
|
||||
@@ -49,12 +49,12 @@ namespace Umbraco.Web.Cache
|
||||
foreach (var payload in payloads)
|
||||
{
|
||||
foreach (var alias in GetCacheKeysForAlias(payload.Alias))
|
||||
AppCaches.RuntimeCache.ClearCacheByKeySearch(alias);
|
||||
AppCaches.RuntimeCache.ClearByKey(alias);
|
||||
|
||||
var macroRepoCache = AppCaches.IsolatedRuntimeCache.GetCache<IMacro>();
|
||||
var macroRepoCache = AppCaches.IsolatedCaches.Get<IMacro>();
|
||||
if (macroRepoCache)
|
||||
{
|
||||
macroRepoCache.Result.ClearCacheItem(RepositoryCacheKeys.GetKey<IMacro>(payload.Id));
|
||||
macroRepoCache.Result.Clear(RepositoryCacheKeys.GetKey<IMacro>(payload.Id));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -112,7 +112,7 @@ namespace Umbraco.Web.Cache
|
||||
|
||||
public static void ClearMacroContentCache(AppCaches appCaches)
|
||||
{
|
||||
appCaches.RuntimeCache.ClearCacheObjectTypes<MacroCacheContent>();
|
||||
appCaches.RuntimeCache.ClearOfType<MacroCacheContent>();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace Umbraco.Web.Cache
|
||||
{
|
||||
Current.ApplicationCache.ClearPartialViewCache();
|
||||
|
||||
var mediaCache = AppCaches.IsolatedRuntimeCache.GetCache<IMedia>();
|
||||
var mediaCache = AppCaches.IsolatedCaches.Get<IMedia>();
|
||||
|
||||
foreach (var payload in payloads)
|
||||
{
|
||||
@@ -61,13 +61,13 @@ namespace Umbraco.Web.Cache
|
||||
// repository cache
|
||||
// it *was* done for each pathId but really that does not make sense
|
||||
// only need to do it for the current media
|
||||
mediaCache.Result.ClearCacheItem(RepositoryCacheKeys.GetKey<IMedia>(payload.Id));
|
||||
mediaCache.Result.Clear(RepositoryCacheKeys.GetKey<IMedia>(payload.Id));
|
||||
|
||||
// remove those that are in the branch
|
||||
if (payload.ChangeTypes.HasTypesAny(TreeChangeTypes.RefreshBranch | TreeChangeTypes.Remove))
|
||||
{
|
||||
var pathid = "," + payload.Id + ",";
|
||||
mediaCache.Result.ClearCacheObjectTypes<IMedia>((_, v) => v.Path.Contains(pathid));
|
||||
mediaCache.Result.ClearOfType<IMedia>((_, v) => v.Path.Contains(pathid));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -121,7 +121,7 @@ namespace Umbraco.Web.Cache
|
||||
|
||||
public static void RefreshMediaTypes(AppCaches appCaches)
|
||||
{
|
||||
appCaches.IsolatedRuntimeCache.ClearCache<IMedia>();
|
||||
appCaches.IsolatedCaches.ClearCache<IMedia>();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -60,9 +60,9 @@ namespace Umbraco.Web.Cache
|
||||
_idkMap.ClearCache(id);
|
||||
AppCaches.ClearPartialViewCache();
|
||||
|
||||
var memberCache = AppCaches.IsolatedRuntimeCache.GetCache<IMember>();
|
||||
var memberCache = AppCaches.IsolatedCaches.Get<IMember>();
|
||||
if (memberCache)
|
||||
memberCache.Result.ClearCacheItem(RepositoryCacheKeys.GetKey<IMember>(id));
|
||||
memberCache.Result.Clear(RepositoryCacheKeys.GetKey<IMember>(id));
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -71,7 +71,7 @@ namespace Umbraco.Web.Cache
|
||||
|
||||
public static void RefreshMemberTypes(AppCaches appCaches)
|
||||
{
|
||||
appCaches.IsolatedRuntimeCache.ClearCache<IMember>();
|
||||
appCaches.IsolatedCaches.ClearCache<IMember>();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace Umbraco.Web.Cache
|
||||
// Since we cache by group name, it could be problematic when renaming to
|
||||
// previously existing names - see http://issues.umbraco.org/issue/U4-10846.
|
||||
// To work around this, just clear all the cache items
|
||||
AppCaches.IsolatedRuntimeCache.ClearCache<IMemberGroup>();
|
||||
AppCaches.IsolatedCaches.ClearCache<IMemberGroup>();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -34,8 +34,8 @@ namespace Umbraco.Web.Cache
|
||||
|
||||
public override void Refresh(int id)
|
||||
{
|
||||
var cache = AppCaches.IsolatedRuntimeCache.GetCache<IRelationType>();
|
||||
if (cache) cache.Result.ClearCacheItem(RepositoryCacheKeys.GetKey<IRelationType>(id));
|
||||
var cache = AppCaches.IsolatedCaches.Get<IRelationType>();
|
||||
if (cache) cache.Result.Clear(RepositoryCacheKeys.GetKey<IRelationType>(id));
|
||||
base.Refresh(id);
|
||||
}
|
||||
|
||||
@@ -47,8 +47,8 @@ namespace Umbraco.Web.Cache
|
||||
|
||||
public override void Remove(int id)
|
||||
{
|
||||
var cache = AppCaches.IsolatedRuntimeCache.GetCache<IRelationType>();
|
||||
if (cache) cache.Result.ClearCacheItem(RepositoryCacheKeys.GetKey<IRelationType>(id));
|
||||
var cache = AppCaches.IsolatedCaches.Get<IRelationType>();
|
||||
if (cache) cache.Result.Clear(RepositoryCacheKeys.GetKey<IRelationType>(id));
|
||||
base.Remove(id);
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace Umbraco.Web.Cache
|
||||
private void RemoveFromCache(int id)
|
||||
{
|
||||
_idkMap.ClearCache(id);
|
||||
AppCaches.RuntimeCache.ClearCacheItem($"{CacheKeys.TemplateFrontEndCacheKey}{id}");
|
||||
AppCaches.RuntimeCache.Clear($"{CacheKeys.TemplateFrontEndCacheKey}{id}");
|
||||
|
||||
//need to clear the runtime cache for templates
|
||||
ClearAllIsolatedCacheByEntityType<ITemplate>();
|
||||
|
||||
@@ -40,9 +40,9 @@ namespace Umbraco.Web.Cache
|
||||
|
||||
public override void Remove(int id)
|
||||
{
|
||||
var userCache = AppCaches.IsolatedRuntimeCache.GetCache<IUser>();
|
||||
var userCache = AppCaches.IsolatedCaches.Get<IUser>();
|
||||
if (userCache)
|
||||
userCache.Result.ClearCacheItem(RepositoryCacheKeys.GetKey<IUser>(id));
|
||||
userCache.Result.Clear(RepositoryCacheKeys.GetKey<IUser>(id));
|
||||
|
||||
base.Remove(id);
|
||||
}
|
||||
|
||||
@@ -35,10 +35,10 @@ namespace Umbraco.Web.Cache
|
||||
public override void RefreshAll()
|
||||
{
|
||||
ClearAllIsolatedCacheByEntityType<IUserGroup>();
|
||||
var userGroupCache = AppCaches.IsolatedRuntimeCache.GetCache<IUserGroup>();
|
||||
var userGroupCache = AppCaches.IsolatedCaches.Get<IUserGroup>();
|
||||
if (userGroupCache)
|
||||
{
|
||||
userGroupCache.Result.ClearCacheByKeySearch(UserGroupRepository.GetByAliasCacheKeyPrefix);
|
||||
userGroupCache.Result.ClearByKey(UserGroupRepository.GetByAliasCacheKeyPrefix);
|
||||
}
|
||||
|
||||
//We'll need to clear all user cache too
|
||||
@@ -55,11 +55,11 @@ namespace Umbraco.Web.Cache
|
||||
|
||||
public override void Remove(int id)
|
||||
{
|
||||
var userGroupCache = AppCaches.IsolatedRuntimeCache.GetCache<IUserGroup>();
|
||||
var userGroupCache = AppCaches.IsolatedCaches.Get<IUserGroup>();
|
||||
if (userGroupCache)
|
||||
{
|
||||
userGroupCache.Result.ClearCacheItem(RepositoryCacheKeys.GetKey<IUserGroup>(id));
|
||||
userGroupCache.Result.ClearCacheByKeySearch(UserGroupRepository.GetByAliasCacheKeyPrefix);
|
||||
userGroupCache.Result.Clear(RepositoryCacheKeys.GetKey<IUserGroup>(id));
|
||||
userGroupCache.Result.ClearByKey(UserGroupRepository.GetByAliasCacheKeyPrefix);
|
||||
}
|
||||
|
||||
//we don't know what user's belong to this group without doing a look up so we'll need to just clear them all
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace Umbraco.Web
|
||||
/// <param name="appCaches"></param>
|
||||
public static void ClearPartialViewCache(this AppCaches appCaches)
|
||||
{
|
||||
appCaches.RuntimeCache.ClearCacheByKeySearch(PartialViewCacheKey);
|
||||
appCaches.RuntimeCache.ClearByKey(PartialViewCacheKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace Umbraco.Web.Dictionary
|
||||
public class DefaultCultureDictionary : Core.Dictionary.ICultureDictionary
|
||||
{
|
||||
private readonly ILocalizationService _localizationService;
|
||||
private readonly ICacheProvider _requestCacheProvider;
|
||||
private readonly IAppCache _requestCacheProvider;
|
||||
private readonly CultureInfo _specificCulture;
|
||||
|
||||
public DefaultCultureDictionary()
|
||||
@@ -30,7 +30,7 @@ namespace Umbraco.Web.Dictionary
|
||||
|
||||
}
|
||||
|
||||
public DefaultCultureDictionary(ILocalizationService localizationService, ICacheProvider requestCacheProvider)
|
||||
public DefaultCultureDictionary(ILocalizationService localizationService, IAppCache requestCacheProvider)
|
||||
{
|
||||
_localizationService = localizationService ?? throw new ArgumentNullException(nameof(localizationService));
|
||||
_requestCacheProvider = requestCacheProvider ?? throw new ArgumentNullException(nameof(requestCacheProvider));
|
||||
@@ -42,7 +42,7 @@ namespace Umbraco.Web.Dictionary
|
||||
_specificCulture = specificCulture ?? throw new ArgumentNullException(nameof(specificCulture));
|
||||
}
|
||||
|
||||
public DefaultCultureDictionary(CultureInfo specificCulture, ILocalizationService localizationService, ICacheProvider requestCacheProvider)
|
||||
public DefaultCultureDictionary(CultureInfo specificCulture, ILocalizationService localizationService, IAppCache requestCacheProvider)
|
||||
{
|
||||
_localizationService = localizationService ?? throw new ArgumentNullException(nameof(localizationService));
|
||||
_requestCacheProvider = requestCacheProvider ?? throw new ArgumentNullException(nameof(requestCacheProvider));
|
||||
|
||||
@@ -29,12 +29,12 @@ namespace Umbraco.Web.Editors
|
||||
{
|
||||
private readonly IExamineManager _examineManager;
|
||||
private readonly ILogger _logger;
|
||||
private readonly IRuntimeCacheProvider _runtimeCacheProvider;
|
||||
private readonly IAppPolicedCache _runtimeCacheProvider;
|
||||
private readonly IndexRebuilder _indexRebuilder;
|
||||
|
||||
|
||||
public ExamineManagementController(IExamineManager examineManager, ILogger logger,
|
||||
IRuntimeCacheProvider runtimeCacheProvider,
|
||||
IAppPolicedCache runtimeCacheProvider,
|
||||
IndexRebuilder indexRebuilder)
|
||||
{
|
||||
_examineManager = examineManager;
|
||||
@@ -114,7 +114,7 @@ namespace Umbraco.Web.Editors
|
||||
throw new HttpResponseException(validate);
|
||||
|
||||
var cacheKey = "temp_indexing_op_" + indexName;
|
||||
var found = ApplicationCache.RuntimeCache.GetCacheItem(cacheKey);
|
||||
var found = ApplicationCache.RuntimeCache.Get(cacheKey);
|
||||
|
||||
//if its still there then it's not done
|
||||
return found != null
|
||||
@@ -153,7 +153,7 @@ namespace Umbraco.Web.Editors
|
||||
|
||||
var cacheKey = "temp_indexing_op_" + index.Name;
|
||||
//put temp val in cache which is used as a rudimentary way to know when the indexing is done
|
||||
ApplicationCache.RuntimeCache.InsertCacheItem(cacheKey, () => "tempValue", TimeSpan.FromMinutes(5));
|
||||
ApplicationCache.RuntimeCache.Insert(cacheKey, () => "tempValue", TimeSpan.FromMinutes(5));
|
||||
|
||||
_indexRebuilder.RebuildIndex(indexName);
|
||||
|
||||
@@ -269,7 +269,7 @@ namespace Umbraco.Web.Editors
|
||||
>($"Rebuilding index '{indexer.Name}' done, {indexer.CommitCount} items committed (can differ from the number of items in the index)");
|
||||
|
||||
var cacheKey = "temp_indexing_op_" + indexer.Name;
|
||||
_runtimeCacheProvider.ClearCacheItem(cacheKey);
|
||||
_runtimeCacheProvider.Clear(cacheKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace Umbraco.Web.Editors
|
||||
return await PostSetAvatarInternal(Request, Services.UserService, ApplicationCache.StaticCache, id);
|
||||
}
|
||||
|
||||
internal static async Task<HttpResponseMessage> PostSetAvatarInternal(HttpRequestMessage request, IUserService userService, ICacheProvider staticCache, int id)
|
||||
internal static async Task<HttpResponseMessage> PostSetAvatarInternal(HttpRequestMessage request, IUserService userService, IAppCache staticCache, int id)
|
||||
{
|
||||
if (request.Content.IsMimeMultipartContent() == false)
|
||||
{
|
||||
|
||||
@@ -152,7 +152,7 @@ namespace Umbraco.Web.Macros
|
||||
macroContent.Date = DateTime.Now;
|
||||
|
||||
var cache = Current.ApplicationCache.RuntimeCache;
|
||||
cache.InsertCacheItem(
|
||||
cache.Insert(
|
||||
CacheKeys.MacroContentCacheKey + model.CacheIdentifier,
|
||||
() => macroContent,
|
||||
new TimeSpan(0, 0, model.CacheDuration),
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Umbraco.Web.Models.Mapping
|
||||
=> entity is ContentEntitySlim contentEntity ? contentEntity.ContentTypeIcon : null;
|
||||
|
||||
public UserMapperProfile(ILocalizedTextService textService, IUserService userService, IEntityService entityService, ISectionService sectionService,
|
||||
IRuntimeCacheProvider runtimeCache, ActionCollection actions, IGlobalSettings globalSettings)
|
||||
IAppPolicedCache runtimeCache, ActionCollection actions, IGlobalSettings globalSettings)
|
||||
{
|
||||
var userGroupDefaultPermissionsResolver = new UserGroupDefaultPermissionsResolver(textService, actions);
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace Umbraco.Web.PublishedCache
|
||||
/// <remarks>
|
||||
/// <para>The snapshot-level cache belongs to this snapshot only.</para>
|
||||
/// </remarks>
|
||||
ICacheProvider SnapshotCache { get; }
|
||||
IAppCache SnapshotCache { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the elements-level cache.
|
||||
@@ -45,7 +45,7 @@ namespace Umbraco.Web.PublishedCache
|
||||
/// <para>The elements-level cache is shared by all snapshots relying on the same elements,
|
||||
/// ie all snapshots built on top of unchanging content / media / etc.</para>
|
||||
/// </remarks>
|
||||
ICacheProvider ElementsCache { get; }
|
||||
IAppCache ElementsCache { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Forces the preview mode.
|
||||
|
||||
@@ -21,8 +21,8 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
internal class ContentCache : PublishedCacheBase, IPublishedContentCache, INavigableData, IDisposable
|
||||
{
|
||||
private readonly ContentStore.Snapshot _snapshot;
|
||||
private readonly ICacheProvider _snapshotCache;
|
||||
private readonly ICacheProvider _elementsCache;
|
||||
private readonly IAppCache _snapshotCache;
|
||||
private readonly IAppCache _elementsCache;
|
||||
private readonly DomainHelper _domainHelper;
|
||||
private readonly IGlobalSettings _globalSettings;
|
||||
private readonly ILocalizationService _localizationService;
|
||||
@@ -34,7 +34,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
// it's too late for UmbracoContext which has captured previewDefault and stuff into these ctor vars
|
||||
// but, no, UmbracoContext returns snapshot.Content which comes from elements SO a resync should create a new cache
|
||||
|
||||
public ContentCache(bool previewDefault, ContentStore.Snapshot snapshot, ICacheProvider snapshotCache, ICacheProvider elementsCache, DomainHelper domainHelper, IGlobalSettings globalSettings, ILocalizationService localizationService)
|
||||
public ContentCache(bool previewDefault, ContentStore.Snapshot snapshot, IAppCache snapshotCache, IAppCache elementsCache, DomainHelper domainHelper, IGlobalSettings globalSettings, ILocalizationService localizationService)
|
||||
: base(previewDefault)
|
||||
{
|
||||
_snapshot = snapshot;
|
||||
@@ -259,7 +259,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
return GetAtRootNoCache(preview);
|
||||
|
||||
// note: ToArray is important here, we want to cache the result, not the function!
|
||||
return (IEnumerable<IPublishedContent>)cache.GetCacheItem(
|
||||
return (IEnumerable<IPublishedContent>)cache.Get(
|
||||
CacheKeys.ContentCacheRoots(preview),
|
||||
() => GetAtRootNoCache(preview).ToArray());
|
||||
}
|
||||
|
||||
@@ -13,12 +13,12 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
internal class MediaCache : PublishedCacheBase, IPublishedMediaCache, INavigableData, IDisposable
|
||||
{
|
||||
private readonly ContentStore.Snapshot _snapshot;
|
||||
private readonly ICacheProvider _snapshotCache;
|
||||
private readonly ICacheProvider _elementsCache;
|
||||
private readonly IAppCache _snapshotCache;
|
||||
private readonly IAppCache _elementsCache;
|
||||
|
||||
#region Constructors
|
||||
|
||||
public MediaCache(bool previewDefault, ContentStore.Snapshot snapshot, ICacheProvider snapshotCache, ICacheProvider elementsCache)
|
||||
public MediaCache(bool previewDefault, ContentStore.Snapshot snapshot, IAppCache snapshotCache, IAppCache elementsCache)
|
||||
: base(previewDefault)
|
||||
{
|
||||
_snapshot = snapshot;
|
||||
@@ -63,7 +63,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
return GetAtRootNoCache();
|
||||
|
||||
// note: ToArray is important here, we want to cache the result, not the function!
|
||||
return (IEnumerable<IPublishedContent>)cache.GetCacheItem(
|
||||
return (IEnumerable<IPublishedContent>)cache.Get(
|
||||
CacheKeys.MediaCacheRoots(false), // ignore preview, only 1 key!
|
||||
() => GetAtRootNoCache().ToArray());
|
||||
}
|
||||
|
||||
@@ -19,12 +19,12 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
private readonly IPublishedSnapshotAccessor _publishedSnapshotAccessor;
|
||||
public readonly IVariationContextAccessor VariationContextAccessor;
|
||||
private readonly IEntityXmlSerializer _entitySerializer;
|
||||
private readonly ICacheProvider _snapshotCache;
|
||||
private readonly IAppCache _snapshotCache;
|
||||
private readonly IMemberService _memberService;
|
||||
private readonly PublishedContentTypeCache _contentTypeCache;
|
||||
private readonly bool _previewDefault;
|
||||
|
||||
public MemberCache(bool previewDefault, ICacheProvider snapshotCache, IMemberService memberService, PublishedContentTypeCache contentTypeCache, IPublishedSnapshotAccessor publishedSnapshotAccessor, IVariationContextAccessor variationContextAccessor, IEntityXmlSerializer entitySerializer)
|
||||
public MemberCache(bool previewDefault, IAppCache snapshotCache, IMemberService memberService, PublishedContentTypeCache contentTypeCache, IPublishedSnapshotAccessor publishedSnapshotAccessor, IVariationContextAccessor variationContextAccessor, IEntityXmlSerializer entitySerializer)
|
||||
{
|
||||
_snapshotCache = snapshotCache;
|
||||
_publishedSnapshotAccessor = publishedSnapshotAccessor;
|
||||
|
||||
@@ -125,7 +125,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
{
|
||||
CacheValues cacheValues;
|
||||
PublishedSnapshot publishedSnapshot;
|
||||
ICacheProvider cache;
|
||||
IAppCache cache;
|
||||
switch (cacheLevel)
|
||||
{
|
||||
case PropertyCacheLevel.None:
|
||||
@@ -161,11 +161,11 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
return cacheValues;
|
||||
}
|
||||
|
||||
private CacheValues GetCacheValues(ICacheProvider cache)
|
||||
private CacheValues GetCacheValues(IAppCache cache)
|
||||
{
|
||||
if (cache == null) // no cache, don't cache
|
||||
return new CacheValues();
|
||||
return (CacheValues) cache.GetCacheItem(ValuesCacheKey, () => new CacheValues());
|
||||
return (CacheValues) cache.Get(ValuesCacheKey, () => new CacheValues());
|
||||
}
|
||||
|
||||
// this is always invoked from within a lock, so does not require its own lock
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
var cache = GetCurrentSnapshotCache();
|
||||
return cache == null
|
||||
? GetProfileNameByIdNoCache(id)
|
||||
: (string)cache.GetCacheItem(CacheKeys.ProfileName(id), () => GetProfileNameByIdNoCache(id));
|
||||
: (string)cache.Get(CacheKeys.ProfileName(id), () => GetProfileNameByIdNoCache(id));
|
||||
}
|
||||
|
||||
private static string GetProfileNameByIdNoCache(int id)
|
||||
@@ -328,7 +328,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
return GetChildren();
|
||||
|
||||
// note: ToArray is important here, we want to cache the result, not the function!
|
||||
return (IEnumerable<IPublishedContent>)cache.GetCacheItem(ChildrenCacheKey, () => GetChildren().ToArray());
|
||||
return (IEnumerable<IPublishedContent>)cache.Get(ChildrenCacheKey, () => GetChildren().ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -383,7 +383,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
#region Caching
|
||||
|
||||
// beware what you use that one for - you don't want to cache its result
|
||||
private ICacheProvider GetAppropriateCache()
|
||||
private IAppCache GetAppropriateCache()
|
||||
{
|
||||
var publishedSnapshot = (PublishedSnapshot)_publishedSnapshotAccessor.PublishedSnapshot;
|
||||
var cache = publishedSnapshot == null
|
||||
@@ -394,7 +394,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
return cache;
|
||||
}
|
||||
|
||||
private ICacheProvider GetCurrentSnapshotCache()
|
||||
private IAppCache GetCurrentSnapshotCache()
|
||||
{
|
||||
var publishedSnapshot = (PublishedSnapshot)_publishedSnapshotAccessor.PublishedSnapshot;
|
||||
return publishedSnapshot?.SnapshotCache;
|
||||
@@ -436,7 +436,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
|
||||
var cache = GetAppropriateCache();
|
||||
if (cache == null) return new PublishedContent(this).CreateModel();
|
||||
return (IPublishedContent)cache.GetCacheItem(AsPreviewingCacheKey, () => new PublishedContent(this).CreateModel());
|
||||
return (IPublishedContent)cache.Get(AsPreviewingCacheKey, () => new PublishedContent(this).CreateModel());
|
||||
}
|
||||
|
||||
// used by Navigable.Source,...
|
||||
|
||||
@@ -25,8 +25,8 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
public MediaCache MediaCache;
|
||||
public MemberCache MemberCache;
|
||||
public DomainCache DomainCache;
|
||||
public ICacheProvider SnapshotCache;
|
||||
public ICacheProvider ElementsCache;
|
||||
public IAppCache SnapshotCache;
|
||||
public IAppCache ElementsCache;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
@@ -48,9 +48,9 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
|
||||
#region Caches
|
||||
|
||||
public ICacheProvider SnapshotCache => Elements.SnapshotCache;
|
||||
public IAppCache SnapshotCache => Elements.SnapshotCache;
|
||||
|
||||
public ICacheProvider ElementsCache => Elements.ElementsCache;
|
||||
public IAppCache ElementsCache => Elements.ElementsCache;
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -932,7 +932,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
#region Create, Get Published Snapshot
|
||||
|
||||
private long _contentGen, _mediaGen, _domainGen;
|
||||
private ICacheProvider _elementsCache;
|
||||
private IAppCache _elementsCache;
|
||||
|
||||
public override IPublishedSnapshot CreatePublishedSnapshot(string previewToken)
|
||||
{
|
||||
@@ -960,7 +960,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
|
||||
ContentStore.Snapshot contentSnap, mediaSnap;
|
||||
SnapDictionary<int, Domain>.Snapshot domainSnap;
|
||||
ICacheProvider elementsCache;
|
||||
IAppCache elementsCache;
|
||||
lock (_storesLock)
|
||||
{
|
||||
var scopeContext = _scopeProvider.Context;
|
||||
@@ -998,11 +998,11 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
_contentGen = contentSnap.Gen;
|
||||
_mediaGen = mediaSnap.Gen;
|
||||
_domainGen = domainSnap.Gen;
|
||||
elementsCache = _elementsCache = new DictionaryCacheProvider();
|
||||
elementsCache = _elementsCache = new FastDictionaryCacheProvider();
|
||||
}
|
||||
}
|
||||
|
||||
var snapshotCache = new StaticCacheProvider();
|
||||
var snapshotCache = new DictionaryCacheProvider();
|
||||
|
||||
var memberTypeCache = new PublishedContentTypeCache(null, null, _serviceContext.MemberTypeService, _publishedContentTypeFactory, _logger);
|
||||
|
||||
|
||||
@@ -106,7 +106,7 @@ namespace Umbraco.Web.PublishedCache
|
||||
}
|
||||
}
|
||||
|
||||
private ICacheProvider GetSnapshotCache()
|
||||
private IAppCache GetSnapshotCache()
|
||||
{
|
||||
// cache within the snapshot cache, unless previewing, then use the snapshot or
|
||||
// elements cache (if we don't want to pollute the elements cache with short-lived
|
||||
@@ -135,12 +135,12 @@ namespace Umbraco.Web.PublishedCache
|
||||
case PropertyCacheLevel.Elements:
|
||||
// cache within the elements cache, depending...
|
||||
var snapshotCache = GetSnapshotCache();
|
||||
cacheValues = (CacheValues) snapshotCache?.GetCacheItem(ValuesCacheKey, () => new CacheValues()) ?? new CacheValues();
|
||||
cacheValues = (CacheValues) snapshotCache?.Get(ValuesCacheKey, () => new CacheValues()) ?? new CacheValues();
|
||||
break;
|
||||
case PropertyCacheLevel.Snapshot:
|
||||
// cache within the snapshot cache
|
||||
var facadeCache = _publishedSnapshotAccessor?.PublishedSnapshot?.SnapshotCache;
|
||||
cacheValues = (CacheValues) facadeCache?.GetCacheItem(ValuesCacheKey, () => new CacheValues()) ?? new CacheValues();
|
||||
cacheValues = (CacheValues) facadeCache?.Get(ValuesCacheKey, () => new CacheValues()) ?? new CacheValues();
|
||||
break;
|
||||
default:
|
||||
throw new InvalidOperationException("Invalid cache level.");
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
|
||||
Func<int, IPublishedContent> getParent,
|
||||
Func<int, XPathNavigator, IEnumerable<IPublishedContent>> getChildren,
|
||||
Func<DictionaryPublishedContent, string, IPublishedProperty> getProperty,
|
||||
ICacheProvider cacheProvider,
|
||||
IAppCache cacheProvider,
|
||||
PublishedContentTypeCache contentTypeCache,
|
||||
XPathNavigator nav,
|
||||
bool fromExamine)
|
||||
@@ -133,7 +133,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
|
||||
//private readonly Func<DictionaryPublishedContent, IEnumerable<IPublishedContent>> _getChildren;
|
||||
private readonly Lazy<IEnumerable<IPublishedContent>> _getChildren;
|
||||
private readonly Func<DictionaryPublishedContent, string, IPublishedProperty> _getProperty;
|
||||
private readonly ICacheProvider _cacheProvider;
|
||||
private readonly IAppCache _cacheProvider;
|
||||
|
||||
/// <summary>
|
||||
/// Returns 'Media' as the item type
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
|
||||
{
|
||||
internal class PublishedContentCache : PublishedCacheBase, IPublishedContentCache
|
||||
{
|
||||
private readonly ICacheProvider _cacheProvider;
|
||||
private readonly IAppCache _cacheProvider;
|
||||
private readonly IGlobalSettings _globalSettings;
|
||||
private readonly RoutesCache _routesCache;
|
||||
private readonly IDomainCache _domainCache;
|
||||
@@ -30,7 +30,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
|
||||
public PublishedContentCache(
|
||||
XmlStore xmlStore, // an XmlStore containing the master xml
|
||||
IDomainCache domainCache, // an IDomainCache implementation
|
||||
ICacheProvider cacheProvider, // an ICacheProvider that should be at request-level
|
||||
IAppCache cacheProvider, // an ICacheProvider that should be at request-level
|
||||
IGlobalSettings globalSettings,
|
||||
ISiteDomainHelper siteDomainHelper,
|
||||
PublishedContentTypeCache contentTypeCache, // a PublishedContentType cache
|
||||
@@ -517,7 +517,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
|
||||
// clear recursive properties cached by XmlPublishedContent.GetProperty
|
||||
// assume that nothing else is going to cache IPublishedProperty items (else would need to do ByKeySearch)
|
||||
// NOTE also clears all the media cache properties, which is OK (see media cache)
|
||||
_cacheProvider.ClearCacheObjectTypes<IPublishedProperty>();
|
||||
_cacheProvider.ClearOfType<IPublishedProperty>();
|
||||
//_cacheProvider.ClearCacheByKeySearch("XmlPublishedCache.PublishedContentCache:RecursiveProperty-");
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user