diff --git a/Sdl.Web.Common/packages.config b/Sdl.Web.Common/packages.config index a966e523..8f502d5c 100644 --- a/Sdl.Web.Common/packages.config +++ b/Sdl.Web.Common/packages.config @@ -1,11 +1,11 @@  - - - - - - - + + + + + + + \ No newline at end of file diff --git a/Sdl.Web.Mvc/packages.config b/Sdl.Web.Mvc/packages.config index 6eca069a..0792b155 100644 --- a/Sdl.Web.Mvc/packages.config +++ b/Sdl.Web.Mvc/packages.config @@ -1,9 +1,9 @@  - - - - - - + + + + + + \ No newline at end of file diff --git a/Sdl.Web.Tridion/Providers/Caching/KeylockCacheProvider.cs b/Sdl.Web.Tridion/Providers/Caching/KeylockCacheProvider.cs index a372cac1..48e45337 100644 --- a/Sdl.Web.Tridion/Providers/Caching/KeylockCacheProvider.cs +++ b/Sdl.Web.Tridion/Providers/Caching/KeylockCacheProvider.cs @@ -1,11 +1,10 @@ -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Diagnostics; -using System.Threading; +using AsyncKeyedLock; using Sdl.Web.Common; using Sdl.Web.Common.Interfaces; using Sdl.Web.Delivery.Caching; +using System; +using System.Collections.Generic; +using System.Diagnostics; namespace Sdl.Web.Tridion.Caching { @@ -26,35 +25,26 @@ namespace Sdl.Web.Tridion.Caching /// public class KeylockCacheProvider : ICacheProvider { - private static readonly ConcurrentDictionary KeyLocks = new ConcurrentDictionary(); + private static readonly AsyncKeyedLocker _asyncKeyedLocker = new AsyncKeyedLocker(o => + { + o.PoolSize = 20; + o.PoolInitialFill = 1; + }); private readonly ICacheProvider _cilCacheProvider = CacheFactory.CreateFromConfiguration(); - [ThreadStatic] - private static int _reentriesCount; - public void Store(string key, string region, T value, IEnumerable dependencies = null) { Debug.Assert(_cilCacheProvider != null, "_cilCacheProvider != null"); // prevent deadlocks if we're storing something here and in GetOrAdd. var hash = CalcLockHash(key, region); - lock (KeyLocks.GetOrAdd(hash, new object())) + using (_asyncKeyedLocker.Lock(hash)) { - try - { - T cachedValue; - // only add if we are sure it hasn't already been added - if (!TryGetCachedValue(key, region, out cachedValue)) - { - _cilCacheProvider.Set(key, value, region); - } - } - finally + // only add if we are sure it hasn't already been added + if (!TryGetCachedValue(key, region, out T cachedValue)) { - // We don't need the lock anymore - object tempKeyLock; - KeyLocks.TryRemove(hash, out tempKeyLock); + _cilCacheProvider.Set(key, value, region); } } } @@ -63,37 +53,25 @@ public void Store(string key, string region, T value, IEnumerable dep public T GetOrAdd(string key, string region, Func addFunction, IEnumerable dependencies = null) { - T cachedValue; - if (TryGetCachedValue(key, region, out cachedValue)) return cachedValue; + if (TryGetCachedValue(key, region, out T cachedValue)) return cachedValue; var hash = CalcLockHash(key, region); - lock (KeyLocks.GetOrAdd(hash, new object())) + using (_asyncKeyedLocker.Lock(hash)) { - try - { - // Try and get from cache again in case it has been added in the meantime - if (TryGetCachedValue(key, region, out cachedValue)) return cachedValue; + // Try and get from cache again in case it has been added in the meantime + if (TryGetCachedValue(key, region, out cachedValue)) return cachedValue; - // Still null, so lets run Func() - Interlocked.Increment(ref _reentriesCount); - cachedValue = addFunction(); - if (cachedValue != null) + // Still null, so lets run Func() + cachedValue = addFunction(); + if (cachedValue != null) + { + // Note that dependencies are not used? + Debug.Assert(_cilCacheProvider != null, "_cilCacheProvider != null"); + if (_cilCacheProvider.Get(key, region) == null) { - // Note that dependencies are not used? - Debug.Assert(_cilCacheProvider != null, "_cilCacheProvider != null"); - if (_cilCacheProvider.Get(key, region) == null) - { - _cilCacheProvider.Set(key, cachedValue, region); - } - - return cachedValue; + _cilCacheProvider.Set(key, cachedValue, region); } - } - finally - { - Interlocked.Decrement(ref _reentriesCount); - // We don't need the lock anymore - object tempKeyLock; - KeyLocks.TryRemove(hash, out tempKeyLock); + + return cachedValue; } } return default(T); @@ -117,6 +95,6 @@ private bool TryGetCachedValue(string key, string region, out T value) return false; } - private static string CalcLockHash(string key, string region) => $"{region}:{key}:{_reentriesCount}"; + private static string CalcLockHash(string key, string region) => $"{region}:{key}"; } } diff --git a/Sdl.Web.Tridion/Sdl.Web.Tridion.csproj b/Sdl.Web.Tridion/Sdl.Web.Tridion.csproj index e95d7080..6cd37fa9 100644 --- a/Sdl.Web.Tridion/Sdl.Web.Tridion.csproj +++ b/Sdl.Web.Tridion/Sdl.Web.Tridion.csproj @@ -55,6 +55,9 @@ + + ..\packages\AsyncKeyedLock.7.0.1\lib\netstandard2.0\AsyncKeyedLock.dll + ..\packages\DD4T.Core.2.2.7\lib\net45\DD4T.ContentModel.dll @@ -166,6 +169,9 @@ + + ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.3\lib\net461\System.Runtime.CompilerServices.Unsafe.dll + ..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll @@ -173,6 +179,9 @@ ..\packages\System.Spatial.5.8.4\lib\net40\System.Spatial.dll True + + ..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll + @@ -261,6 +270,7 @@ + Designer diff --git a/Sdl.Web.Tridion/app.config b/Sdl.Web.Tridion/app.config new file mode 100644 index 00000000..5150bb27 --- /dev/null +++ b/Sdl.Web.Tridion/app.config @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Sdl.Web.Tridion/packages.config b/Sdl.Web.Tridion/packages.config index e76815de..fdb20a3a 100644 --- a/Sdl.Web.Tridion/packages.config +++ b/Sdl.Web.Tridion/packages.config @@ -1,26 +1,29 @@  - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - + + + + \ No newline at end of file diff --git a/Site/Web.config b/Site/Web.config index c704ba95..e4929ac6 100644 --- a/Site/Web.config +++ b/Site/Web.config @@ -1,89 +1,89 @@ -
-
-
+
+
+
-
+
- - + + - + - + - + - - - + + + - - - - - - - - + + + + + + + + - + - + - + - + - + - + - - + + - - + + - - - - - + + + + + - - - - - - - - - + + + + + + + + + - + @@ -96,183 +96,187 @@ --> - - + + - - + + - - - - - - + + + + + + - + - + - - + + - + - + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + + + + + - - + + - - + + diff --git a/Site/packages.config b/Site/packages.config index e333477b..54b1be96 100644 --- a/Site/packages.config +++ b/Site/packages.config @@ -1,36 +1,36 @@  - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + \ No newline at end of file