From c0532bf4a63d6e2cf1d0bd25d1bd36f9c7c84711 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Delaporte?= <12201973+fredericdelaporte@users.noreply.github.com> Date: Sun, 20 Sep 2020 19:28:30 +0200 Subject: [PATCH 1/6] Avoid NRE in cache strategies --- .../Async/Cache/NonstrictReadWriteCache.cs | 23 +++++++--- src/NHibernate/Async/Cache/ReadOnlyCache.cs | 26 ++++++++++- src/NHibernate/Async/Cache/ReadWriteCache.cs | 45 ++++++++++++++++--- src/NHibernate/Cache/CacheFactory.cs | 2 +- .../Cache/NonstrictReadWriteCache.cs | 21 ++++++++- src/NHibernate/Cache/ReadOnlyCache.cs | 18 +++++++- src/NHibernate/Cache/ReadWriteCache.cs | 24 +++++++++- 7 files changed, 141 insertions(+), 18 deletions(-) diff --git a/src/NHibernate/Async/Cache/NonstrictReadWriteCache.cs b/src/NHibernate/Async/Cache/NonstrictReadWriteCache.cs index da86e36832a..4a916649e87 100644 --- a/src/NHibernate/Async/Cache/NonstrictReadWriteCache.cs +++ b/src/NHibernate/Async/Cache/NonstrictReadWriteCache.cs @@ -8,6 +8,7 @@ //------------------------------------------------------------------------------ +using System; using System.Collections; using System.Collections.Generic; using System.Linq; @@ -26,6 +27,7 @@ public partial class NonstrictReadWriteCache : IBatchableCacheConcurrencyStrateg public async Task GetAsync(CacheKey key, long txTimestamp, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); + CheckCache(); if (log.IsDebugEnabled()) { log.Debug("Cache lookup: {0}", key); @@ -43,6 +45,7 @@ public async Task GetAsync(CacheKey key, long txTimestamp, CancellationT public async Task GetManyAsync(CacheKey[] keys, long timestamp, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); + CheckCache(); if (log.IsDebugEnabled()) { log.Debug("Cache lookup: {0}", string.Join(",", keys.AsEnumerable())); @@ -73,6 +76,8 @@ public async Task PutManyAsync( return result; } + CheckCache(); + var checkKeys = new List(); var checkKeyIndexes = new List(); for (var i = 0; i < minimalPuts.Length; i++) @@ -135,6 +140,8 @@ public async Task PutAsync(CacheKey key, object value, long txTimestamp, o return false; } + CheckCache(); + if (minimalPut && await (Cache.GetAsync(key, cancellationToken)).ConfigureAwait(false) != null) { if (log.IsDebugEnabled()) @@ -164,7 +171,7 @@ public Task LockAsync(CacheKey key, object version, CancellationToken { return Task.FromResult(Lock(key, version)); } - catch (System.Exception ex) + catch (Exception ex) { return Task.FromException(ex); } @@ -178,13 +185,14 @@ public Task RemoveAsync(CacheKey key, CancellationToken cancellationToken) } try { + CheckCache(); if (log.IsDebugEnabled()) { log.Debug("Removing: {0}", key); } return Cache.RemoveAsync(key, cancellationToken); } - catch (System.Exception ex) + catch (Exception ex) { return Task.FromException(ex); } @@ -198,13 +206,14 @@ public Task ClearAsync(CancellationToken cancellationToken) } try { + CheckCache(); if (log.IsDebugEnabled()) { log.Debug("Clearing"); } return Cache.ClearAsync(cancellationToken); } - catch (System.Exception ex) + catch (Exception ex) { return Task.FromException(ex); } @@ -221,13 +230,14 @@ public Task EvictAsync(CacheKey key, CancellationToken cancellationToken) } try { + CheckCache(); if (log.IsDebugEnabled()) { log.Debug("Invalidating: {0}", key); } return Cache.RemoveAsync(key, cancellationToken); } - catch (System.Exception ex) + catch (Exception ex) { return Task.FromException(ex); } @@ -254,6 +264,7 @@ public Task ReleaseAsync(CacheKey key, ISoftLock @lock, CancellationToken cancel } try { + CheckCache(); if (log.IsDebugEnabled()) { log.Debug("Invalidating (again): {0}", key); @@ -261,7 +272,7 @@ public Task ReleaseAsync(CacheKey key, ISoftLock @lock, CancellationToken cancel return Cache.RemoveAsync(key, cancellationToken); } - catch (System.Exception ex) + catch (Exception ex) { return Task.FromException(ex); } @@ -290,7 +301,7 @@ public Task AfterInsertAsync(CacheKey key, object value, object version, C { return Task.FromResult(AfterInsert(key, value, version)); } - catch (System.Exception ex) + catch (Exception ex) { return Task.FromException(ex); } diff --git a/src/NHibernate/Async/Cache/ReadOnlyCache.cs b/src/NHibernate/Async/Cache/ReadOnlyCache.cs index b87852ed39b..b3abd5d4e04 100644 --- a/src/NHibernate/Async/Cache/ReadOnlyCache.cs +++ b/src/NHibernate/Async/Cache/ReadOnlyCache.cs @@ -24,6 +24,7 @@ public partial class ReadOnlyCache : IBatchableCacheConcurrencyStrategy public async Task GetAsync(CacheKey key, long timestamp, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); + CheckCache(); var result = await (Cache.GetAsync(key, cancellationToken)).ConfigureAwait(false); if (log.IsDebugEnabled()) { @@ -36,6 +37,7 @@ public async Task GetAsync(CacheKey key, long timestamp, CancellationTok public async Task GetManyAsync(CacheKey[] keys, long timestamp, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); + CheckCache(); if (log.IsDebugEnabled()) { log.Debug("Cache lookup: {0}", string.Join(",", keys.AsEnumerable())); @@ -82,6 +84,8 @@ public async Task PutManyAsync( return result; } + CheckCache(); + var checkKeys = new List(); var checkKeyIndexes = new List(); for (var i = 0; i < minimalPuts.Length; i++) @@ -141,6 +145,8 @@ public async Task PutAsync(CacheKey key, object value, long timestamp, obj return false; } + CheckCache(); + if (minimalPut && await (Cache.GetAsync(key, cancellationToken)).ConfigureAwait(false) != null) { if (log.IsDebugEnabled()) @@ -183,7 +189,15 @@ public Task ClearAsync(CancellationToken cancellationToken) { return Task.FromCanceled(cancellationToken); } - return Cache.ClearAsync(cancellationToken); + try + { + CheckCache(); + return Cache.ClearAsync(cancellationToken); + } + catch (Exception ex) + { + return Task.FromException(ex); + } } public Task RemoveAsync(CacheKey key, CancellationToken cancellationToken) @@ -192,7 +206,15 @@ public Task RemoveAsync(CacheKey key, CancellationToken cancellationToken) { return Task.FromCanceled(cancellationToken); } - return Cache.RemoveAsync(key, cancellationToken); + try + { + CheckCache(); + return Cache.RemoveAsync(key, cancellationToken); + } + catch (Exception ex) + { + return Task.FromException(ex); + } } /// diff --git a/src/NHibernate/Async/Cache/ReadWriteCache.cs b/src/NHibernate/Async/Cache/ReadWriteCache.cs index eac3b2bc339..de1de020a19 100644 --- a/src/NHibernate/Async/Cache/ReadWriteCache.cs +++ b/src/NHibernate/Async/Cache/ReadWriteCache.cs @@ -8,6 +8,7 @@ //------------------------------------------------------------------------------ +using System; using System.Collections; using System.Collections.Generic; using System.Linq; @@ -40,6 +41,8 @@ public partial class ReadWriteCache : IBatchableCacheConcurrencyStrategy /// public async Task GetAsync(CacheKey key, long txTimestamp, CancellationToken cancellationToken) { + cancellationToken.ThrowIfCancellationRequested(); + CheckCache(); cancellationToken.ThrowIfCancellationRequested(); using (await (_asyncReaderWriterLock.ReadLockAsync()).ConfigureAwait(false)) { @@ -65,6 +68,7 @@ public async Task GetAsync(CacheKey key, long txTimestamp, CancellationT public async Task GetManyAsync(CacheKey[] keys, long timestamp, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); + CheckCache(); if (log.IsDebugEnabled()) { log.Debug("Cache lookup: {0}", string.Join(",", keys.AsEnumerable())); @@ -92,6 +96,8 @@ public async Task GetManyAsync(CacheKey[] keys, long timestamp, Cancel /// public async Task LockAsync(CacheKey key, object version, CancellationToken cancellationToken) { + cancellationToken.ThrowIfCancellationRequested(); + CheckCache(); cancellationToken.ThrowIfCancellationRequested(); using (await (_asyncReaderWriterLock.WriteLockAsync()).ConfigureAwait(false)) { @@ -136,6 +142,8 @@ public async Task PutManyAsync( // MinValue means cache is disabled return result; } + + CheckCache(); cancellationToken.ThrowIfCancellationRequested(); using (await (_asyncReaderWriterLock.WriteLockAsync()).ConfigureAwait(false)) @@ -207,6 +215,8 @@ public async Task PutAsync(CacheKey key, object value, long txTimestamp, o // MinValue means cache is disabled return false; } + + CheckCache(); cancellationToken.ThrowIfCancellationRequested(); using (await (_asyncReaderWriterLock.WriteLockAsync()).ConfigureAwait(false)) @@ -264,7 +274,7 @@ private Task DecrementLockAsync(object key, CacheLock @lock, CancellationToken c @lock.Unlock(Cache.NextTimestamp()); return Cache.PutAsync(key, @lock, cancellationToken); } - catch (System.Exception ex) + catch (Exception ex) { return Task.FromException(ex); } @@ -272,6 +282,8 @@ private Task DecrementLockAsync(object key, CacheLock @lock, CancellationToken c public async Task ReleaseAsync(CacheKey key, ISoftLock clientLock, CancellationToken cancellationToken) { + cancellationToken.ThrowIfCancellationRequested(); + CheckCache(); cancellationToken.ThrowIfCancellationRequested(); using (await (_asyncReaderWriterLock.WriteLockAsync()).ConfigureAwait(false)) { @@ -308,6 +320,7 @@ internal Task HandleLockExpiryAsync(object key, CancellationToken cancellationTo } try { + CheckCache(); log.Warn("An item was expired by the cache while it was locked (increase your cache timeout): {0}", key); long ts = Cache.NextTimestamp() + Cache.Timeout; // create new lock that times out immediately @@ -315,7 +328,7 @@ internal Task HandleLockExpiryAsync(object key, CancellationToken cancellationTo @lock.Unlock(ts); return Cache.PutAsync(key, @lock, cancellationToken); } - catch (System.Exception ex) + catch (Exception ex) { return Task.FromException(ex); } @@ -327,7 +340,15 @@ public Task ClearAsync(CancellationToken cancellationToken) { return Task.FromCanceled(cancellationToken); } - return Cache.ClearAsync(cancellationToken); + try + { + CheckCache(); + return Cache.ClearAsync(cancellationToken); + } + catch (Exception ex) + { + return Task.FromException(ex); + } } public Task RemoveAsync(CacheKey key, CancellationToken cancellationToken) @@ -336,7 +357,15 @@ public Task RemoveAsync(CacheKey key, CancellationToken cancellationToken) { return Task.FromCanceled(cancellationToken); } - return Cache.RemoveAsync(key, cancellationToken); + try + { + CheckCache(); + return Cache.RemoveAsync(key, cancellationToken); + } + catch (Exception ex) + { + return Task.FromException(ex); + } } /// @@ -345,6 +374,8 @@ public Task RemoveAsync(CacheKey key, CancellationToken cancellationToken) /// public async Task AfterUpdateAsync(CacheKey key, object value, object version, ISoftLock clientLock, CancellationToken cancellationToken) { + cancellationToken.ThrowIfCancellationRequested(); + CheckCache(); cancellationToken.ThrowIfCancellationRequested(); using (await (_asyncReaderWriterLock.WriteLockAsync()).ConfigureAwait(false)) { @@ -392,6 +423,8 @@ public async Task AfterUpdateAsync(CacheKey key, object value, object vers public async Task AfterInsertAsync(CacheKey key, object value, object version, CancellationToken cancellationToken) { + cancellationToken.ThrowIfCancellationRequested(); + CheckCache(); cancellationToken.ThrowIfCancellationRequested(); using (await (_asyncReaderWriterLock.WriteLockAsync()).ConfigureAwait(false)) { @@ -436,7 +469,7 @@ public Task EvictAsync(CacheKey key, CancellationToken cancellationToken) Evict(key); return Task.CompletedTask; } - catch (System.Exception ex) + catch (Exception ex) { return Task.FromException(ex); } @@ -452,7 +485,7 @@ public Task UpdateAsync(CacheKey key, object value, object currentVersion, { return Task.FromResult(Update(key, value, currentVersion, previousVersion)); } - catch (System.Exception ex) + catch (Exception ex) { return Task.FromException(ex); } diff --git a/src/NHibernate/Cache/CacheFactory.cs b/src/NHibernate/Cache/CacheFactory.cs index b6c5df8549d..27c1150bbad 100644 --- a/src/NHibernate/Cache/CacheFactory.cs +++ b/src/NHibernate/Cache/CacheFactory.cs @@ -60,7 +60,7 @@ public static ICacheConcurrencyStrategy CreateCache( public static ICacheConcurrencyStrategy CreateCache(string usage, CacheBase cache) { if (log.IsDebugEnabled()) - log.Debug("cache for: {0} usage strategy: {1}", cache.RegionName, usage); + log.Debug("cache for: {0} usage strategy: {1}", cache?.RegionName, usage); ICacheConcurrencyStrategy ccs; switch (usage) diff --git a/src/NHibernate/Cache/NonstrictReadWriteCache.cs b/src/NHibernate/Cache/NonstrictReadWriteCache.cs index 011a2c9b7be..587e981da5c 100644 --- a/src/NHibernate/Cache/NonstrictReadWriteCache.cs +++ b/src/NHibernate/Cache/NonstrictReadWriteCache.cs @@ -1,3 +1,4 @@ +using System; using System.Collections; using System.Collections.Generic; using System.Linq; @@ -18,13 +19,14 @@ public partial class NonstrictReadWriteCache : IBatchableCacheConcurrencyStrateg private static readonly INHibernateLogger log = NHibernateLogger.For(typeof(NonstrictReadWriteCache)); private CacheBase _cache; + private bool _isDestroyed; /// /// Gets the cache region name. /// public string RegionName { - get { return Cache.RegionName; } + get { return Cache?.RegionName; } } // 6.0 TODO: remove @@ -48,6 +50,7 @@ CacheBase IBatchableCacheConcurrencyStrategy.Cache /// public object Get(CacheKey key, long txTimestamp) { + CheckCache(); if (log.IsDebugEnabled()) { log.Debug("Cache lookup: {0}", key); @@ -64,6 +67,7 @@ public object Get(CacheKey key, long txTimestamp) public object[] GetMany(CacheKey[] keys, long timestamp) { + CheckCache(); if (log.IsDebugEnabled()) { log.Debug("Cache lookup: {0}", string.Join(",", keys.AsEnumerable())); @@ -93,6 +97,8 @@ public bool[] PutMany( return result; } + CheckCache(); + var checkKeys = new List(); var checkKeyIndexes = new List(); for (var i = 0; i < minimalPuts.Length; i++) @@ -154,6 +160,8 @@ public bool Put(CacheKey key, object value, long txTimestamp, object version, IC return false; } + CheckCache(); + if (minimalPut && Cache.Get(key) != null) { if (log.IsDebugEnabled()) @@ -180,6 +188,7 @@ public ISoftLock Lock(CacheKey key, object version) public void Remove(CacheKey key) { + CheckCache(); if (log.IsDebugEnabled()) { log.Debug("Removing: {0}", key); @@ -189,6 +198,7 @@ public void Remove(CacheKey key) public void Clear() { + CheckCache(); if (log.IsDebugEnabled()) { log.Debug("Clearing"); @@ -200,6 +210,7 @@ public void Destroy() { // The cache is externally provided and may be shared. Destroying the cache is // not the responsibility of this class. + _isDestroyed = true; Cache = null; } @@ -208,6 +219,7 @@ public void Destroy() /// public void Evict(CacheKey key) { + CheckCache(); if (log.IsDebugEnabled()) { log.Debug("Invalidating: {0}", key); @@ -237,6 +249,7 @@ public bool Insert(CacheKey key, object value, object currentVersion) /// public void Release(CacheKey key, ISoftLock @lock) { + CheckCache(); if (log.IsDebugEnabled()) { log.Debug("Invalidating (again): {0}", key); @@ -261,5 +274,11 @@ public bool AfterInsert(CacheKey key, object value, object version) { return false; } + + private void CheckCache() + { + if (_cache == null || _isDestroyed) + throw new InvalidOperationException(_isDestroyed ? "The cache has already been destroyed" : "The concrete cache is not defined"); + } } } diff --git a/src/NHibernate/Cache/ReadOnlyCache.cs b/src/NHibernate/Cache/ReadOnlyCache.cs index e95ec9c3475..c6ebcea5251 100644 --- a/src/NHibernate/Cache/ReadOnlyCache.cs +++ b/src/NHibernate/Cache/ReadOnlyCache.cs @@ -14,13 +14,14 @@ public partial class ReadOnlyCache : IBatchableCacheConcurrencyStrategy private static readonly INHibernateLogger log = NHibernateLogger.For(typeof(ReadOnlyCache)); private CacheBase _cache; + private bool _isDestroyed; /// /// Gets the cache region name. /// public string RegionName { - get { return Cache.RegionName; } + get { return Cache?.RegionName; } } // 6.0 TODO: remove @@ -41,6 +42,7 @@ CacheBase IBatchableCacheConcurrencyStrategy.Cache public object Get(CacheKey key, long timestamp) { + CheckCache(); var result = Cache.Get(key); if (log.IsDebugEnabled()) { @@ -52,6 +54,7 @@ public object Get(CacheKey key, long timestamp) public object[] GetMany(CacheKey[] keys, long timestamp) { + CheckCache(); if (log.IsDebugEnabled()) { log.Debug("Cache lookup: {0}", string.Join(",", keys.AsEnumerable())); @@ -87,6 +90,8 @@ public bool[] PutMany( return result; } + CheckCache(); + var checkKeys = new List(); var checkKeyIndexes = new List(); for (var i = 0; i < minimalPuts.Length; i++) @@ -145,6 +150,8 @@ public bool Put(CacheKey key, object value, long timestamp, object version, ICom return false; } + CheckCache(); + if (minimalPut && Cache.Get(key) != null) { if (log.IsDebugEnabled()) @@ -171,11 +178,13 @@ public void Release(CacheKey key, ISoftLock @lock) public void Clear() { + CheckCache(); Cache.Clear(); } public void Remove(CacheKey key) { + CheckCache(); Cache.Remove(key); } @@ -183,6 +192,7 @@ public void Destroy() { // The cache is externally provided and may be shared. Destroying the cache is // not the responsibility of this class. + _isDestroyed = true; Cache = null; } @@ -228,5 +238,11 @@ public bool Update(CacheKey key, object value, object currentVersion, object pre log.Error("Application attempted to edit read only item: {0}", key); throw new InvalidOperationException("ReadOnlyCache: Can't write to a readonly object " + key.EntityOrRoleName); } + + private void CheckCache() + { + if (_cache == null || _isDestroyed) + throw new InvalidOperationException(_isDestroyed ? "The cache has already been destroyed" : "The concrete cache is not defined"); + } } } diff --git a/src/NHibernate/Cache/ReadWriteCache.cs b/src/NHibernate/Cache/ReadWriteCache.cs index 9bb25e51048..64fca0fb7cc 100644 --- a/src/NHibernate/Cache/ReadWriteCache.cs +++ b/src/NHibernate/Cache/ReadWriteCache.cs @@ -1,3 +1,4 @@ +using System; using System.Collections; using System.Collections.Generic; using System.Linq; @@ -35,6 +36,7 @@ public interface ILockable private static readonly INHibernateLogger log = NHibernateLogger.For(typeof(ReadWriteCache)); private CacheBase _cache; + private bool _isDestroyed; private int _nextLockId; private readonly AsyncReaderWriterLock _asyncReaderWriterLock = new AsyncReaderWriterLock(); @@ -43,7 +45,7 @@ public interface ILockable /// public string RegionName { - get { return Cache.RegionName; } + get { return Cache?.RegionName; } } // 6.0 TODO: remove @@ -96,6 +98,7 @@ private int NextLockId() /// public object Get(CacheKey key, long txTimestamp) { + CheckCache(); using (_asyncReaderWriterLock.ReadLock()) { if (log.IsDebugEnabled()) @@ -119,6 +122,7 @@ public object Get(CacheKey key, long txTimestamp) public object[] GetMany(CacheKey[] keys, long timestamp) { + CheckCache(); if (log.IsDebugEnabled()) { log.Debug("Cache lookup: {0}", string.Join(",", keys.AsEnumerable())); @@ -167,6 +171,7 @@ private static object GetValue(long timestamp, CacheKey key, ILockable lockable) /// public ISoftLock Lock(CacheKey key, object version) { + CheckCache(); using (_asyncReaderWriterLock.WriteLock()) { if (log.IsDebugEnabled()) @@ -210,6 +215,8 @@ public bool[] PutMany( return result; } + CheckCache(); + using (_asyncReaderWriterLock.WriteLock()) { if (log.IsDebugEnabled()) @@ -279,6 +286,8 @@ public bool Put(CacheKey key, object value, long txTimestamp, object version, IC return false; } + CheckCache(); + using (_asyncReaderWriterLock.WriteLock()) { if (log.IsDebugEnabled()) @@ -331,6 +340,7 @@ private void DecrementLock(object key, CacheLock @lock) public void Release(CacheKey key, ISoftLock clientLock) { + CheckCache(); using (_asyncReaderWriterLock.WriteLock()) { if (log.IsDebugEnabled()) @@ -360,6 +370,7 @@ public void Release(CacheKey key, ISoftLock clientLock) internal void HandleLockExpiry(object key) { + CheckCache(); log.Warn("An item was expired by the cache while it was locked (increase your cache timeout): {0}", key); long ts = Cache.NextTimestamp() + Cache.Timeout; // create new lock that times out immediately @@ -370,11 +381,13 @@ internal void HandleLockExpiry(object key) public void Clear() { + CheckCache(); Cache.Clear(); } public void Remove(CacheKey key) { + CheckCache(); Cache.Remove(key); } @@ -382,6 +395,7 @@ public void Destroy() { // The cache is externally provided and may be shared. Destroying the cache is // not the responsibility of this class. + _isDestroyed = true; Cache = null; _asyncReaderWriterLock.Dispose(); } @@ -392,6 +406,7 @@ public void Destroy() /// public bool AfterUpdate(CacheKey key, object value, object version, ISoftLock clientLock) { + CheckCache(); using (_asyncReaderWriterLock.WriteLock()) { if (log.IsDebugEnabled()) @@ -438,6 +453,7 @@ public bool AfterUpdate(CacheKey key, object value, object version, ISoftLock cl public bool AfterInsert(CacheKey key, object value, object version) { + CheckCache(); using (_asyncReaderWriterLock.WriteLock()) { if (log.IsDebugEnabled()) @@ -498,5 +514,11 @@ private bool IsUnlockable(ISoftLock clientLock, ILockable myLock) clientLock != null && ((CacheLock) clientLock).Id == ((CacheLock) myLock).Id; } + + private void CheckCache() + { + if (_cache == null || _isDestroyed) + throw new InvalidOperationException(_isDestroyed ? "The cache has already been destroyed" : "The concrete cache is not defined"); + } } } From 996696d6ab48aa2e21f87943a5d4697555d66b77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Delaporte?= <12201973+fredericDelaporte@users.noreply.github.com> Date: Thu, 24 Sep 2020 20:25:36 +0200 Subject: [PATCH 2/6] Reduce the bloat with review suggestions --- .../Async/Cache/NonstrictReadWriteCache.cs | 33 ++--- src/NHibernate/Async/Cache/ReadOnlyCache.cs | 41 ++----- src/NHibernate/Async/Cache/ReadWriteCache.cs | 102 +++++++--------- .../Cache/NonstrictReadWriteCache.cs | 57 +++++---- src/NHibernate/Cache/ReadOnlyCache.cs | 53 ++++---- src/NHibernate/Cache/ReadWriteCache.cs | 114 +++++++++--------- 6 files changed, 181 insertions(+), 219 deletions(-) diff --git a/src/NHibernate/Async/Cache/NonstrictReadWriteCache.cs b/src/NHibernate/Async/Cache/NonstrictReadWriteCache.cs index 4a916649e87..bd8fe846c02 100644 --- a/src/NHibernate/Async/Cache/NonstrictReadWriteCache.cs +++ b/src/NHibernate/Async/Cache/NonstrictReadWriteCache.cs @@ -27,13 +27,12 @@ public partial class NonstrictReadWriteCache : IBatchableCacheConcurrencyStrateg public async Task GetAsync(CacheKey key, long txTimestamp, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); - CheckCache(); if (log.IsDebugEnabled()) { log.Debug("Cache lookup: {0}", key); } - var result = await (Cache.GetAsync(key, cancellationToken)).ConfigureAwait(false); + var result = await (InternalCache.GetAsync(key, cancellationToken)).ConfigureAwait(false); if (log.IsDebugEnabled()) { log.Debug(result != null ? "Cache hit: {0}" : "Cache miss: {0}", key); @@ -45,13 +44,12 @@ public async Task GetAsync(CacheKey key, long txTimestamp, CancellationT public async Task GetManyAsync(CacheKey[] keys, long timestamp, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); - CheckCache(); if (log.IsDebugEnabled()) { log.Debug("Cache lookup: {0}", string.Join(",", keys.AsEnumerable())); } - var results = await (_cache.GetManyAsync(keys, cancellationToken)).ConfigureAwait(false); + var results = await (InternalCache.GetManyAsync(keys, cancellationToken)).ConfigureAwait(false); if (log.IsDebugEnabled()) { log.Debug("Cache hit: {0}", string.Join(",", keys.Where((k, i) => results != null))); @@ -76,8 +74,6 @@ public async Task PutManyAsync( return result; } - CheckCache(); - var checkKeys = new List(); var checkKeyIndexes = new List(); for (var i = 0; i < minimalPuts.Length; i++) @@ -88,10 +84,12 @@ public async Task PutManyAsync( checkKeyIndexes.Add(i); } } + + var cache = InternalCache; var skipKeyIndexes = new HashSet(); if (checkKeys.Any()) { - var objects = await (_cache.GetManyAsync(checkKeys.ToArray(), cancellationToken)).ConfigureAwait(false); + var objects = await (cache.GetManyAsync(checkKeys.ToArray(), cancellationToken)).ConfigureAwait(false); for (var i = 0; i < objects.Length; i++) { if (objects[i] != null) @@ -123,7 +121,7 @@ public async Task PutManyAsync( putValues[j++] = values[i]; result[i] = true; } - await (_cache.PutManyAsync(putKeys, putValues, cancellationToken)).ConfigureAwait(false); + await (cache.PutManyAsync(putKeys, putValues, cancellationToken)).ConfigureAwait(false); return result; } @@ -140,9 +138,8 @@ public async Task PutAsync(CacheKey key, object value, long txTimestamp, o return false; } - CheckCache(); - - if (minimalPut && await (Cache.GetAsync(key, cancellationToken)).ConfigureAwait(false) != null) + var cache = InternalCache; + if (minimalPut && await (cache.GetAsync(key, cancellationToken)).ConfigureAwait(false) != null) { if (log.IsDebugEnabled()) { @@ -154,7 +151,7 @@ public async Task PutAsync(CacheKey key, object value, long txTimestamp, o { log.Debug("Caching: {0}", key); } - await (Cache.PutAsync(key, value, cancellationToken)).ConfigureAwait(false); + await (cache.PutAsync(key, value, cancellationToken)).ConfigureAwait(false); return true; } @@ -185,12 +182,11 @@ public Task RemoveAsync(CacheKey key, CancellationToken cancellationToken) } try { - CheckCache(); if (log.IsDebugEnabled()) { log.Debug("Removing: {0}", key); } - return Cache.RemoveAsync(key, cancellationToken); + return InternalCache.RemoveAsync(key, cancellationToken); } catch (Exception ex) { @@ -206,12 +202,11 @@ public Task ClearAsync(CancellationToken cancellationToken) } try { - CheckCache(); if (log.IsDebugEnabled()) { log.Debug("Clearing"); } - return Cache.ClearAsync(cancellationToken); + return InternalCache.ClearAsync(cancellationToken); } catch (Exception ex) { @@ -230,12 +225,11 @@ public Task EvictAsync(CacheKey key, CancellationToken cancellationToken) } try { - CheckCache(); if (log.IsDebugEnabled()) { log.Debug("Invalidating: {0}", key); } - return Cache.RemoveAsync(key, cancellationToken); + return InternalCache.RemoveAsync(key, cancellationToken); } catch (Exception ex) { @@ -264,13 +258,12 @@ public Task ReleaseAsync(CacheKey key, ISoftLock @lock, CancellationToken cancel } try { - CheckCache(); if (log.IsDebugEnabled()) { log.Debug("Invalidating (again): {0}", key); } - return Cache.RemoveAsync(key, cancellationToken); + return InternalCache.RemoveAsync(key, cancellationToken); } catch (Exception ex) { diff --git a/src/NHibernate/Async/Cache/ReadOnlyCache.cs b/src/NHibernate/Async/Cache/ReadOnlyCache.cs index b3abd5d4e04..65610093cea 100644 --- a/src/NHibernate/Async/Cache/ReadOnlyCache.cs +++ b/src/NHibernate/Async/Cache/ReadOnlyCache.cs @@ -24,8 +24,7 @@ public partial class ReadOnlyCache : IBatchableCacheConcurrencyStrategy public async Task GetAsync(CacheKey key, long timestamp, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); - CheckCache(); - var result = await (Cache.GetAsync(key, cancellationToken)).ConfigureAwait(false); + var result = await (InternalCache.GetAsync(key, cancellationToken)).ConfigureAwait(false); if (log.IsDebugEnabled()) { log.Debug(result != null ? "Cache hit: {0}" : "Cache miss: {0}", key); @@ -37,13 +36,12 @@ public async Task GetAsync(CacheKey key, long timestamp, CancellationTok public async Task GetManyAsync(CacheKey[] keys, long timestamp, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); - CheckCache(); if (log.IsDebugEnabled()) { log.Debug("Cache lookup: {0}", string.Join(",", keys.AsEnumerable())); } - var results = await (_cache.GetManyAsync(keys, cancellationToken)).ConfigureAwait(false); + var results = await (InternalCache.GetManyAsync(keys, cancellationToken)).ConfigureAwait(false); if (log.IsDebugEnabled()) { log.Debug("Cache hit: {0}", string.Join(",", keys.Where((k, i) => results[i] != null))); @@ -84,8 +82,6 @@ public async Task PutManyAsync( return result; } - CheckCache(); - var checkKeys = new List(); var checkKeyIndexes = new List(); for (var i = 0; i < minimalPuts.Length; i++) @@ -96,10 +92,12 @@ public async Task PutManyAsync( checkKeyIndexes.Add(i); } } + + var cache = InternalCache; var skipKeyIndexes = new HashSet(); if (checkKeys.Any()) { - var objects = await (_cache.GetManyAsync(checkKeys.ToArray(), cancellationToken)).ConfigureAwait(false); + var objects = await (cache.GetManyAsync(checkKeys.ToArray(), cancellationToken)).ConfigureAwait(false); for (var i = 0; i < objects.Length; i++) { if (objects[i] != null) @@ -131,7 +129,7 @@ public async Task PutManyAsync( putValues[j++] = values[i]; result[i] = true; } - await (_cache.PutManyAsync(putKeys, putValues, cancellationToken)).ConfigureAwait(false); + await (cache.PutManyAsync(putKeys, putValues, cancellationToken)).ConfigureAwait(false); return result; } @@ -145,9 +143,8 @@ public async Task PutAsync(CacheKey key, object value, long timestamp, obj return false; } - CheckCache(); - - if (minimalPut && await (Cache.GetAsync(key, cancellationToken)).ConfigureAwait(false) != null) + var cache = InternalCache; + if (minimalPut && await (cache.GetAsync(key, cancellationToken)).ConfigureAwait(false) != null) { if (log.IsDebugEnabled()) { @@ -159,7 +156,7 @@ public async Task PutAsync(CacheKey key, object value, long timestamp, obj { log.Debug("Caching: {0}", key); } - await (Cache.PutAsync(key, value, cancellationToken)).ConfigureAwait(false); + await (cache.PutAsync(key, value, cancellationToken)).ConfigureAwait(false); return true; } @@ -189,15 +186,7 @@ public Task ClearAsync(CancellationToken cancellationToken) { return Task.FromCanceled(cancellationToken); } - try - { - CheckCache(); - return Cache.ClearAsync(cancellationToken); - } - catch (Exception ex) - { - return Task.FromException(ex); - } + return InternalCache.ClearAsync(cancellationToken); } public Task RemoveAsync(CacheKey key, CancellationToken cancellationToken) @@ -206,15 +195,7 @@ public Task RemoveAsync(CacheKey key, CancellationToken cancellationToken) { return Task.FromCanceled(cancellationToken); } - try - { - CheckCache(); - return Cache.RemoveAsync(key, cancellationToken); - } - catch (Exception ex) - { - return Task.FromException(ex); - } + return InternalCache.RemoveAsync(key, cancellationToken); } /// diff --git a/src/NHibernate/Async/Cache/ReadWriteCache.cs b/src/NHibernate/Async/Cache/ReadWriteCache.cs index de1de020a19..a215f30d1e1 100644 --- a/src/NHibernate/Async/Cache/ReadWriteCache.cs +++ b/src/NHibernate/Async/Cache/ReadWriteCache.cs @@ -42,7 +42,7 @@ public partial class ReadWriteCache : IBatchableCacheConcurrencyStrategy public async Task GetAsync(CacheKey key, long txTimestamp, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); - CheckCache(); + var cache = InternalCache; cancellationToken.ThrowIfCancellationRequested(); using (await (_asyncReaderWriterLock.ReadLockAsync()).ConfigureAwait(false)) { @@ -55,7 +55,7 @@ public async Task GetAsync(CacheKey key, long txTimestamp, CancellationT /*try { cache.Lock( key );*/ - var lockable = (ILockable) await (Cache.GetAsync(key, cancellationToken)).ConfigureAwait(false); + var lockable = (ILockable) await (cache.GetAsync(key, cancellationToken)).ConfigureAwait(false); return GetValue(txTimestamp, key, lockable); /*} finally @@ -68,16 +68,16 @@ public async Task GetAsync(CacheKey key, long txTimestamp, CancellationT public async Task GetManyAsync(CacheKey[] keys, long timestamp, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); - CheckCache(); if (log.IsDebugEnabled()) { log.Debug("Cache lookup: {0}", string.Join(",", keys.AsEnumerable())); } + var cache = InternalCache; var result = new object[keys.Length]; cancellationToken.ThrowIfCancellationRequested(); using (await (_asyncReaderWriterLock.ReadLockAsync()).ConfigureAwait(false)) { - var lockables = await (_cache.GetManyAsync(keys, cancellationToken)).ConfigureAwait(false); + var lockables = await (cache.GetManyAsync(keys, cancellationToken)).ConfigureAwait(false); for (var i = 0; i < lockables.Length; i++) { var o = (ILockable) lockables[i]; @@ -97,7 +97,7 @@ public async Task GetManyAsync(CacheKey[] keys, long timestamp, Cancel public async Task LockAsync(CacheKey key, object version, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); - CheckCache(); + var cache = InternalCache; cancellationToken.ThrowIfCancellationRequested(); using (await (_asyncReaderWriterLock.WriteLockAsync()).ConfigureAwait(false)) { @@ -106,20 +106,20 @@ public async Task LockAsync(CacheKey key, object version, Cancellatio log.Debug("Invalidating: {0}", key); } - var lockValue = await (_cache.LockAsync(key, cancellationToken)).ConfigureAwait(false); + var lockValue = await (cache.LockAsync(key, cancellationToken)).ConfigureAwait(false); try { - ILockable lockable = (ILockable) await (Cache.GetAsync(key, cancellationToken)).ConfigureAwait(false); - long timeout = Cache.NextTimestamp() + Cache.Timeout; + ILockable lockable = (ILockable) await (cache.GetAsync(key, cancellationToken)).ConfigureAwait(false); + long timeout = cache.NextTimestamp() + cache.Timeout; CacheLock @lock = lockable == null ? CacheLock.Create(timeout, NextLockId(), version) : lockable.Lock(timeout, NextLockId()); - await (Cache.PutAsync(key, @lock, cancellationToken)).ConfigureAwait(false); + await (cache.PutAsync(key, @lock, cancellationToken)).ConfigureAwait(false); return @lock; } finally { - await (_cache.UnlockAsync(key, lockValue, cancellationToken)).ConfigureAwait(false); + await (cache.UnlockAsync(key, lockValue, cancellationToken)).ConfigureAwait(false); } } } @@ -143,9 +143,8 @@ public async Task PutManyAsync( return result; } - CheckCache(); + var cache = InternalCache; cancellationToken.ThrowIfCancellationRequested(); - using (await (_asyncReaderWriterLock.WriteLockAsync()).ConfigureAwait(false)) { if (log.IsDebugEnabled()) @@ -153,11 +152,11 @@ public async Task PutManyAsync( log.Debug("Caching: {0}", string.Join(",", keys.AsEnumerable())); } - var lockValue = await (_cache.LockManyAsync(keys, cancellationToken)).ConfigureAwait(false); + var lockValue = await (cache.LockManyAsync(keys, cancellationToken)).ConfigureAwait(false); try { var putBatch = new Dictionary(); - var lockables = await (_cache.GetManyAsync(keys, cancellationToken)).ConfigureAwait(false); + var lockables = await (cache.GetManyAsync(keys, cancellationToken)).ConfigureAwait(false); for (var i = 0; i < keys.Length; i++) { var key = keys[i]; @@ -167,7 +166,7 @@ public async Task PutManyAsync( lockable.IsPuttable(timestamp, version, versionComparers[i]); if (puttable) { - putBatch.Add(key, CachedItem.Create(values[i], Cache.NextTimestamp(), version)); + putBatch.Add(key, CachedItem.Create(values[i], cache.NextTimestamp(), version)); if (log.IsDebugEnabled()) { log.Debug("Cached: {0}", key); @@ -188,12 +187,12 @@ public async Task PutManyAsync( if (putBatch.Count > 0) { - await (_cache.PutManyAsync(putBatch.Keys.ToArray(), putBatch.Values.ToArray(), cancellationToken)).ConfigureAwait(false); + await (cache.PutManyAsync(putBatch.Keys.ToArray(), putBatch.Values.ToArray(), cancellationToken)).ConfigureAwait(false); } } finally { - await (_cache.UnlockManyAsync(keys, lockValue, cancellationToken)).ConfigureAwait(false); + await (cache.UnlockManyAsync(keys, lockValue, cancellationToken)).ConfigureAwait(false); } } return result; @@ -216,9 +215,8 @@ public async Task PutAsync(CacheKey key, object value, long txTimestamp, o return false; } - CheckCache(); + var cache = InternalCache; cancellationToken.ThrowIfCancellationRequested(); - using (await (_asyncReaderWriterLock.WriteLockAsync()).ConfigureAwait(false)) { if (log.IsDebugEnabled()) @@ -226,17 +224,17 @@ public async Task PutAsync(CacheKey key, object value, long txTimestamp, o log.Debug("Caching: {0}", key); } - var lockValue = await (_cache.LockAsync(key, cancellationToken)).ConfigureAwait(false); + var lockValue = await (cache.LockAsync(key, cancellationToken)).ConfigureAwait(false); try { - ILockable lockable = (ILockable) await (Cache.GetAsync(key, cancellationToken)).ConfigureAwait(false); + ILockable lockable = (ILockable) await (cache.GetAsync(key, cancellationToken)).ConfigureAwait(false); bool puttable = lockable == null || lockable.IsPuttable(txTimestamp, version, versionComparator); if (puttable) { - await (Cache.PutAsync(key, CachedItem.Create(value, Cache.NextTimestamp(), version), cancellationToken)).ConfigureAwait(false); + await (cache.PutAsync(key, CachedItem.Create(value, cache.NextTimestamp(), version), cancellationToken)).ConfigureAwait(false); if (log.IsDebugEnabled()) { log.Debug("Cached: {0}", key); @@ -254,7 +252,7 @@ public async Task PutAsync(CacheKey key, object value, long txTimestamp, o } finally { - await (_cache.UnlockAsync(key, lockValue, cancellationToken)).ConfigureAwait(false); + await (cache.UnlockAsync(key, lockValue, cancellationToken)).ConfigureAwait(false); } } } @@ -271,8 +269,8 @@ private Task DecrementLockAsync(object key, CacheLock @lock, CancellationToken c try { //decrement the lock - @lock.Unlock(Cache.NextTimestamp()); - return Cache.PutAsync(key, @lock, cancellationToken); + @lock.Unlock(InternalCache.NextTimestamp()); + return InternalCache.PutAsync(key, @lock, cancellationToken); } catch (Exception ex) { @@ -283,7 +281,7 @@ private Task DecrementLockAsync(object key, CacheLock @lock, CancellationToken c public async Task ReleaseAsync(CacheKey key, ISoftLock clientLock, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); - CheckCache(); + var cache = InternalCache; cancellationToken.ThrowIfCancellationRequested(); using (await (_asyncReaderWriterLock.WriteLockAsync()).ConfigureAwait(false)) { @@ -292,10 +290,10 @@ public async Task ReleaseAsync(CacheKey key, ISoftLock clientLock, CancellationT log.Debug("Releasing: {0}", key); } - var lockValue = await (_cache.LockAsync(key, cancellationToken)).ConfigureAwait(false); + var lockValue = await (cache.LockAsync(key, cancellationToken)).ConfigureAwait(false); try { - ILockable lockable = (ILockable) await (Cache.GetAsync(key, cancellationToken)).ConfigureAwait(false); + ILockable lockable = (ILockable) await (cache.GetAsync(key, cancellationToken)).ConfigureAwait(false); if (IsUnlockable(clientLock, lockable)) { await (DecrementLockAsync(key, (CacheLock) lockable, cancellationToken)).ConfigureAwait(false); @@ -307,7 +305,7 @@ public async Task ReleaseAsync(CacheKey key, ISoftLock clientLock, CancellationT } finally { - await (_cache.UnlockAsync(key, lockValue, cancellationToken)).ConfigureAwait(false); + await (cache.UnlockAsync(key, lockValue, cancellationToken)).ConfigureAwait(false); } } } @@ -320,13 +318,13 @@ internal Task HandleLockExpiryAsync(object key, CancellationToken cancellationTo } try { - CheckCache(); log.Warn("An item was expired by the cache while it was locked (increase your cache timeout): {0}", key); - long ts = Cache.NextTimestamp() + Cache.Timeout; + var cache = InternalCache; + long ts = cache.NextTimestamp() + cache.Timeout; // create new lock that times out immediately CacheLock @lock = CacheLock.Create(ts, NextLockId(), null); @lock.Unlock(ts); - return Cache.PutAsync(key, @lock, cancellationToken); + return cache.PutAsync(key, @lock, cancellationToken); } catch (Exception ex) { @@ -340,15 +338,7 @@ public Task ClearAsync(CancellationToken cancellationToken) { return Task.FromCanceled(cancellationToken); } - try - { - CheckCache(); - return Cache.ClearAsync(cancellationToken); - } - catch (Exception ex) - { - return Task.FromException(ex); - } + return InternalCache.ClearAsync(cancellationToken); } public Task RemoveAsync(CacheKey key, CancellationToken cancellationToken) @@ -357,15 +347,7 @@ public Task RemoveAsync(CacheKey key, CancellationToken cancellationToken) { return Task.FromCanceled(cancellationToken); } - try - { - CheckCache(); - return Cache.RemoveAsync(key, cancellationToken); - } - catch (Exception ex) - { - return Task.FromException(ex); - } + return InternalCache.RemoveAsync(key, cancellationToken); } /// @@ -375,7 +357,7 @@ public Task RemoveAsync(CacheKey key, CancellationToken cancellationToken) public async Task AfterUpdateAsync(CacheKey key, object value, object version, ISoftLock clientLock, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); - CheckCache(); + var cache = InternalCache; cancellationToken.ThrowIfCancellationRequested(); using (await (_asyncReaderWriterLock.WriteLockAsync()).ConfigureAwait(false)) { @@ -384,10 +366,10 @@ public async Task AfterUpdateAsync(CacheKey key, object value, object vers log.Debug("Updating: {0}", key); } - var lockValue = await (_cache.LockAsync(key, cancellationToken)).ConfigureAwait(false); + var lockValue = await (cache.LockAsync(key, cancellationToken)).ConfigureAwait(false); try { - ILockable lockable = (ILockable) await (Cache.GetAsync(key, cancellationToken)).ConfigureAwait(false); + ILockable lockable = (ILockable) await (cache.GetAsync(key, cancellationToken)).ConfigureAwait(false); if (IsUnlockable(clientLock, lockable)) { CacheLock @lock = (CacheLock) lockable; @@ -400,7 +382,7 @@ public async Task AfterUpdateAsync(CacheKey key, object value, object vers else { //recache the updated state - await (Cache.PutAsync(key, CachedItem.Create(value, Cache.NextTimestamp(), version), cancellationToken)).ConfigureAwait(false); + await (cache.PutAsync(key, CachedItem.Create(value, cache.NextTimestamp(), version), cancellationToken)).ConfigureAwait(false); if (log.IsDebugEnabled()) { log.Debug("Updated: {0}", key); @@ -416,7 +398,7 @@ public async Task AfterUpdateAsync(CacheKey key, object value, object vers } finally { - await (_cache.UnlockAsync(key, lockValue, cancellationToken)).ConfigureAwait(false); + await (cache.UnlockAsync(key, lockValue, cancellationToken)).ConfigureAwait(false); } } } @@ -424,7 +406,7 @@ public async Task AfterUpdateAsync(CacheKey key, object value, object vers public async Task AfterInsertAsync(CacheKey key, object value, object version, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); - CheckCache(); + var cache = InternalCache; cancellationToken.ThrowIfCancellationRequested(); using (await (_asyncReaderWriterLock.WriteLockAsync()).ConfigureAwait(false)) { @@ -433,13 +415,13 @@ public async Task AfterInsertAsync(CacheKey key, object value, object vers log.Debug("Inserting: {0}", key); } - var lockValue = await (_cache.LockAsync(key, cancellationToken)).ConfigureAwait(false); + var lockValue = await (cache.LockAsync(key, cancellationToken)).ConfigureAwait(false); try { - ILockable lockable = (ILockable) await (Cache.GetAsync(key, cancellationToken)).ConfigureAwait(false); + ILockable lockable = (ILockable) await (cache.GetAsync(key, cancellationToken)).ConfigureAwait(false); if (lockable == null) { - await (Cache.PutAsync(key, CachedItem.Create(value, Cache.NextTimestamp(), version), cancellationToken)).ConfigureAwait(false); + await (cache.PutAsync(key, CachedItem.Create(value, cache.NextTimestamp(), version), cancellationToken)).ConfigureAwait(false); if (log.IsDebugEnabled()) { log.Debug("Inserted: {0}", key); @@ -453,7 +435,7 @@ public async Task AfterInsertAsync(CacheKey key, object value, object vers } finally { - await (_cache.UnlockAsync(key, lockValue, cancellationToken)).ConfigureAwait(false); + await (cache.UnlockAsync(key, lockValue, cancellationToken)).ConfigureAwait(false); } } } diff --git a/src/NHibernate/Cache/NonstrictReadWriteCache.cs b/src/NHibernate/Cache/NonstrictReadWriteCache.cs index 587e981da5c..ec5a70f0fb6 100644 --- a/src/NHibernate/Cache/NonstrictReadWriteCache.cs +++ b/src/NHibernate/Cache/NonstrictReadWriteCache.cs @@ -38,7 +38,19 @@ public ICache Cache set { _cache = value?.AsCacheBase(); } } - // 6.0 TODO: make implicit and switch to auto-property + // 6.0 TODO: Rename to Cache and make public (possible breaking change for reader when null). + private CacheBase InternalCache + { + get + { + if (_cache == null || _isDestroyed) + throw new InvalidOperationException(_isDestroyed ? "The cache has already been destroyed" : "The concrete cache is not defined"); + return _cache; + } + set => _cache = value; + } + + // 6.0 TODO: remove CacheBase IBatchableCacheConcurrencyStrategy.Cache { get => _cache; @@ -50,13 +62,12 @@ CacheBase IBatchableCacheConcurrencyStrategy.Cache /// public object Get(CacheKey key, long txTimestamp) { - CheckCache(); if (log.IsDebugEnabled()) { log.Debug("Cache lookup: {0}", key); } - var result = Cache.Get(key); + var result = InternalCache.Get(key); if (log.IsDebugEnabled()) { log.Debug(result != null ? "Cache hit: {0}" : "Cache miss: {0}", key); @@ -67,13 +78,12 @@ public object Get(CacheKey key, long txTimestamp) public object[] GetMany(CacheKey[] keys, long timestamp) { - CheckCache(); if (log.IsDebugEnabled()) { log.Debug("Cache lookup: {0}", string.Join(",", keys.AsEnumerable())); } - var results = _cache.GetMany(keys); + var results = InternalCache.GetMany(keys); if (log.IsDebugEnabled()) { log.Debug("Cache hit: {0}", string.Join(",", keys.Where((k, i) => results != null))); @@ -97,8 +107,6 @@ public bool[] PutMany( return result; } - CheckCache(); - var checkKeys = new List(); var checkKeyIndexes = new List(); for (var i = 0; i < minimalPuts.Length; i++) @@ -109,10 +117,12 @@ public bool[] PutMany( checkKeyIndexes.Add(i); } } + + var cache = InternalCache; var skipKeyIndexes = new HashSet(); if (checkKeys.Any()) { - var objects = _cache.GetMany(checkKeys.ToArray()); + var objects = cache.GetMany(checkKeys.ToArray()); for (var i = 0; i < objects.Length; i++) { if (objects[i] != null) @@ -144,7 +154,7 @@ public bool[] PutMany( putValues[j++] = values[i]; result[i] = true; } - _cache.PutMany(putKeys, putValues); + cache.PutMany(putKeys, putValues); return result; } @@ -160,9 +170,8 @@ public bool Put(CacheKey key, object value, long txTimestamp, object version, IC return false; } - CheckCache(); - - if (minimalPut && Cache.Get(key) != null) + var cache = InternalCache; + if (minimalPut && cache.Get(key) != null) { if (log.IsDebugEnabled()) { @@ -174,7 +183,7 @@ public bool Put(CacheKey key, object value, long txTimestamp, object version, IC { log.Debug("Caching: {0}", key); } - Cache.Put(key, value); + cache.Put(key, value); return true; } @@ -188,30 +197,28 @@ public ISoftLock Lock(CacheKey key, object version) public void Remove(CacheKey key) { - CheckCache(); if (log.IsDebugEnabled()) { log.Debug("Removing: {0}", key); } - Cache.Remove(key); + InternalCache.Remove(key); } public void Clear() { - CheckCache(); if (log.IsDebugEnabled()) { log.Debug("Clearing"); } - Cache.Clear(); + InternalCache.Clear(); } public void Destroy() { + _isDestroyed = true; // The cache is externally provided and may be shared. Destroying the cache is // not the responsibility of this class. - _isDestroyed = true; - Cache = null; + _cache = null; } /// @@ -219,12 +226,11 @@ public void Destroy() /// public void Evict(CacheKey key) { - CheckCache(); if (log.IsDebugEnabled()) { log.Debug("Invalidating: {0}", key); } - Cache.Remove(key); + InternalCache.Remove(key); } /// @@ -249,13 +255,12 @@ public bool Insert(CacheKey key, object value, object currentVersion) /// public void Release(CacheKey key, ISoftLock @lock) { - CheckCache(); if (log.IsDebugEnabled()) { log.Debug("Invalidating (again): {0}", key); } - Cache.Remove(key); + InternalCache.Remove(key); } /// @@ -274,11 +279,5 @@ public bool AfterInsert(CacheKey key, object value, object version) { return false; } - - private void CheckCache() - { - if (_cache == null || _isDestroyed) - throw new InvalidOperationException(_isDestroyed ? "The cache has already been destroyed" : "The concrete cache is not defined"); - } } } diff --git a/src/NHibernate/Cache/ReadOnlyCache.cs b/src/NHibernate/Cache/ReadOnlyCache.cs index c6ebcea5251..7fbbc1fcfd5 100644 --- a/src/NHibernate/Cache/ReadOnlyCache.cs +++ b/src/NHibernate/Cache/ReadOnlyCache.cs @@ -33,7 +33,19 @@ public ICache Cache set { _cache = value?.AsCacheBase(); } } - // 6.0 TODO: make implicit and switch to auto-property + // 6.0 TODO: Rename to Cache and make public (possible breaking change for reader when null). + private CacheBase InternalCache + { + get + { + if (_cache == null || _isDestroyed) + throw new InvalidOperationException(_isDestroyed ? "The cache has already been destroyed" : "The concrete cache is not defined"); + return _cache; + } + set => _cache = value; + } + + // 6.0 TODO: remove CacheBase IBatchableCacheConcurrencyStrategy.Cache { get => _cache; @@ -42,8 +54,7 @@ CacheBase IBatchableCacheConcurrencyStrategy.Cache public object Get(CacheKey key, long timestamp) { - CheckCache(); - var result = Cache.Get(key); + var result = InternalCache.Get(key); if (log.IsDebugEnabled()) { log.Debug(result != null ? "Cache hit: {0}" : "Cache miss: {0}", key); @@ -54,13 +65,12 @@ public object Get(CacheKey key, long timestamp) public object[] GetMany(CacheKey[] keys, long timestamp) { - CheckCache(); if (log.IsDebugEnabled()) { log.Debug("Cache lookup: {0}", string.Join(",", keys.AsEnumerable())); } - var results = _cache.GetMany(keys); + var results = InternalCache.GetMany(keys); if (log.IsDebugEnabled()) { log.Debug("Cache hit: {0}", string.Join(",", keys.Where((k, i) => results[i] != null))); @@ -90,8 +100,6 @@ public bool[] PutMany( return result; } - CheckCache(); - var checkKeys = new List(); var checkKeyIndexes = new List(); for (var i = 0; i < minimalPuts.Length; i++) @@ -102,10 +110,12 @@ public bool[] PutMany( checkKeyIndexes.Add(i); } } + + var cache = InternalCache; var skipKeyIndexes = new HashSet(); if (checkKeys.Any()) { - var objects = _cache.GetMany(checkKeys.ToArray()); + var objects = cache.GetMany(checkKeys.ToArray()); for (var i = 0; i < objects.Length; i++) { if (objects[i] != null) @@ -137,7 +147,7 @@ public bool[] PutMany( putValues[j++] = values[i]; result[i] = true; } - _cache.PutMany(putKeys, putValues); + cache.PutMany(putKeys, putValues); return result; } @@ -150,9 +160,8 @@ public bool Put(CacheKey key, object value, long timestamp, object version, ICom return false; } - CheckCache(); - - if (minimalPut && Cache.Get(key) != null) + var cache = InternalCache; + if (minimalPut && cache.Get(key) != null) { if (log.IsDebugEnabled()) { @@ -164,7 +173,7 @@ public bool Put(CacheKey key, object value, long timestamp, object version, ICom { log.Debug("Caching: {0}", key); } - Cache.Put(key, value); + cache.Put(key, value); return true; } @@ -178,22 +187,22 @@ public void Release(CacheKey key, ISoftLock @lock) public void Clear() { - CheckCache(); - Cache.Clear(); + InternalCache.Clear(); } public void Remove(CacheKey key) { - CheckCache(); - Cache.Remove(key); + InternalCache.Remove(key); } public void Destroy() { + if (_isDestroyed) + return; + _isDestroyed = true; // The cache is externally provided and may be shared. Destroying the cache is // not the responsibility of this class. - _isDestroyed = true; - Cache = null; + _cache = null; } /// @@ -238,11 +247,5 @@ public bool Update(CacheKey key, object value, object currentVersion, object pre log.Error("Application attempted to edit read only item: {0}", key); throw new InvalidOperationException("ReadOnlyCache: Can't write to a readonly object " + key.EntityOrRoleName); } - - private void CheckCache() - { - if (_cache == null || _isDestroyed) - throw new InvalidOperationException(_isDestroyed ? "The cache has already been destroyed" : "The concrete cache is not defined"); - } } } diff --git a/src/NHibernate/Cache/ReadWriteCache.cs b/src/NHibernate/Cache/ReadWriteCache.cs index 64fca0fb7cc..3a0af63a2ab 100644 --- a/src/NHibernate/Cache/ReadWriteCache.cs +++ b/src/NHibernate/Cache/ReadWriteCache.cs @@ -57,7 +57,19 @@ public ICache Cache set { _cache = value?.AsCacheBase(); } } - // 6.0 TODO: make implicit and switch to auto-property + // 6.0 TODO: Rename to Cache and make public (possible breaking change for reader when null). + private CacheBase InternalCache + { + get + { + if (_cache == null || _isDestroyed) + throw new InvalidOperationException(_isDestroyed ? "The cache has already been destroyed" : "The concrete cache is not defined"); + return _cache; + } + set => _cache = value; + } + + // 6.0 TODO: remove CacheBase IBatchableCacheConcurrencyStrategy.Cache { get => _cache; @@ -98,7 +110,7 @@ private int NextLockId() /// public object Get(CacheKey key, long txTimestamp) { - CheckCache(); + var cache = InternalCache; using (_asyncReaderWriterLock.ReadLock()) { if (log.IsDebugEnabled()) @@ -110,7 +122,7 @@ public object Get(CacheKey key, long txTimestamp) /*try { cache.Lock( key );*/ - var lockable = (ILockable) Cache.Get(key); + var lockable = (ILockable) cache.Get(key); return GetValue(txTimestamp, key, lockable); /*} finally @@ -122,15 +134,15 @@ public object Get(CacheKey key, long txTimestamp) public object[] GetMany(CacheKey[] keys, long timestamp) { - CheckCache(); if (log.IsDebugEnabled()) { log.Debug("Cache lookup: {0}", string.Join(",", keys.AsEnumerable())); } + var cache = InternalCache; var result = new object[keys.Length]; using (_asyncReaderWriterLock.ReadLock()) { - var lockables = _cache.GetMany(keys); + var lockables = cache.GetMany(keys); for (var i = 0; i < lockables.Length; i++) { var o = (ILockable) lockables[i]; @@ -171,7 +183,7 @@ private static object GetValue(long timestamp, CacheKey key, ILockable lockable) /// public ISoftLock Lock(CacheKey key, object version) { - CheckCache(); + var cache = InternalCache; using (_asyncReaderWriterLock.WriteLock()) { if (log.IsDebugEnabled()) @@ -179,20 +191,20 @@ public ISoftLock Lock(CacheKey key, object version) log.Debug("Invalidating: {0}", key); } - var lockValue = _cache.Lock(key); + var lockValue = cache.Lock(key); try { - ILockable lockable = (ILockable) Cache.Get(key); - long timeout = Cache.NextTimestamp() + Cache.Timeout; + ILockable lockable = (ILockable) cache.Get(key); + long timeout = cache.NextTimestamp() + cache.Timeout; CacheLock @lock = lockable == null ? CacheLock.Create(timeout, NextLockId(), version) : lockable.Lock(timeout, NextLockId()); - Cache.Put(key, @lock); + cache.Put(key, @lock); return @lock; } finally { - _cache.Unlock(key, lockValue); + cache.Unlock(key, lockValue); } } } @@ -215,8 +227,7 @@ public bool[] PutMany( return result; } - CheckCache(); - + var cache = InternalCache; using (_asyncReaderWriterLock.WriteLock()) { if (log.IsDebugEnabled()) @@ -224,11 +235,11 @@ public bool[] PutMany( log.Debug("Caching: {0}", string.Join(",", keys.AsEnumerable())); } - var lockValue = _cache.LockMany(keys); + var lockValue = cache.LockMany(keys); try { var putBatch = new Dictionary(); - var lockables = _cache.GetMany(keys); + var lockables = cache.GetMany(keys); for (var i = 0; i < keys.Length; i++) { var key = keys[i]; @@ -238,7 +249,7 @@ public bool[] PutMany( lockable.IsPuttable(timestamp, version, versionComparers[i]); if (puttable) { - putBatch.Add(key, CachedItem.Create(values[i], Cache.NextTimestamp(), version)); + putBatch.Add(key, CachedItem.Create(values[i], cache.NextTimestamp(), version)); if (log.IsDebugEnabled()) { log.Debug("Cached: {0}", key); @@ -259,12 +270,12 @@ public bool[] PutMany( if (putBatch.Count > 0) { - _cache.PutMany(putBatch.Keys.ToArray(), putBatch.Values.ToArray()); + cache.PutMany(putBatch.Keys.ToArray(), putBatch.Values.ToArray()); } } finally { - _cache.UnlockMany(keys, lockValue); + cache.UnlockMany(keys, lockValue); } } return result; @@ -286,8 +297,7 @@ public bool Put(CacheKey key, object value, long txTimestamp, object version, IC return false; } - CheckCache(); - + var cache = InternalCache; using (_asyncReaderWriterLock.WriteLock()) { if (log.IsDebugEnabled()) @@ -295,17 +305,17 @@ public bool Put(CacheKey key, object value, long txTimestamp, object version, IC log.Debug("Caching: {0}", key); } - var lockValue = _cache.Lock(key); + var lockValue = cache.Lock(key); try { - ILockable lockable = (ILockable) Cache.Get(key); + ILockable lockable = (ILockable) cache.Get(key); bool puttable = lockable == null || lockable.IsPuttable(txTimestamp, version, versionComparator); if (puttable) { - Cache.Put(key, CachedItem.Create(value, Cache.NextTimestamp(), version)); + cache.Put(key, CachedItem.Create(value, cache.NextTimestamp(), version)); if (log.IsDebugEnabled()) { log.Debug("Cached: {0}", key); @@ -323,7 +333,7 @@ public bool Put(CacheKey key, object value, long txTimestamp, object version, IC } finally { - _cache.Unlock(key, lockValue); + cache.Unlock(key, lockValue); } } } @@ -334,13 +344,13 @@ public bool Put(CacheKey key, object value, long txTimestamp, object version, IC private void DecrementLock(object key, CacheLock @lock) { //decrement the lock - @lock.Unlock(Cache.NextTimestamp()); - Cache.Put(key, @lock); + @lock.Unlock(InternalCache.NextTimestamp()); + InternalCache.Put(key, @lock); } public void Release(CacheKey key, ISoftLock clientLock) { - CheckCache(); + var cache = InternalCache; using (_asyncReaderWriterLock.WriteLock()) { if (log.IsDebugEnabled()) @@ -348,10 +358,10 @@ public void Release(CacheKey key, ISoftLock clientLock) log.Debug("Releasing: {0}", key); } - var lockValue = _cache.Lock(key); + var lockValue = cache.Lock(key); try { - ILockable lockable = (ILockable) Cache.Get(key); + ILockable lockable = (ILockable) cache.Get(key); if (IsUnlockable(clientLock, lockable)) { DecrementLock(key, (CacheLock) lockable); @@ -363,40 +373,40 @@ public void Release(CacheKey key, ISoftLock clientLock) } finally { - _cache.Unlock(key, lockValue); + cache.Unlock(key, lockValue); } } } internal void HandleLockExpiry(object key) { - CheckCache(); log.Warn("An item was expired by the cache while it was locked (increase your cache timeout): {0}", key); - long ts = Cache.NextTimestamp() + Cache.Timeout; + var cache = InternalCache; + long ts = cache.NextTimestamp() + cache.Timeout; // create new lock that times out immediately CacheLock @lock = CacheLock.Create(ts, NextLockId(), null); @lock.Unlock(ts); - Cache.Put(key, @lock); + cache.Put(key, @lock); } public void Clear() { - CheckCache(); - Cache.Clear(); + InternalCache.Clear(); } public void Remove(CacheKey key) { - CheckCache(); - Cache.Remove(key); + InternalCache.Remove(key); } public void Destroy() { + if (_isDestroyed) + return; + _isDestroyed = true; // The cache is externally provided and may be shared. Destroying the cache is // not the responsibility of this class. - _isDestroyed = true; - Cache = null; + _cache = null; _asyncReaderWriterLock.Dispose(); } @@ -406,7 +416,7 @@ public void Destroy() /// public bool AfterUpdate(CacheKey key, object value, object version, ISoftLock clientLock) { - CheckCache(); + var cache = InternalCache; using (_asyncReaderWriterLock.WriteLock()) { if (log.IsDebugEnabled()) @@ -414,10 +424,10 @@ public bool AfterUpdate(CacheKey key, object value, object version, ISoftLock cl log.Debug("Updating: {0}", key); } - var lockValue = _cache.Lock(key); + var lockValue = cache.Lock(key); try { - ILockable lockable = (ILockable) Cache.Get(key); + ILockable lockable = (ILockable) cache.Get(key); if (IsUnlockable(clientLock, lockable)) { CacheLock @lock = (CacheLock) lockable; @@ -430,7 +440,7 @@ public bool AfterUpdate(CacheKey key, object value, object version, ISoftLock cl else { //recache the updated state - Cache.Put(key, CachedItem.Create(value, Cache.NextTimestamp(), version)); + cache.Put(key, CachedItem.Create(value, cache.NextTimestamp(), version)); if (log.IsDebugEnabled()) { log.Debug("Updated: {0}", key); @@ -446,14 +456,14 @@ public bool AfterUpdate(CacheKey key, object value, object version, ISoftLock cl } finally { - _cache.Unlock(key, lockValue); + cache.Unlock(key, lockValue); } } } public bool AfterInsert(CacheKey key, object value, object version) { - CheckCache(); + var cache = InternalCache; using (_asyncReaderWriterLock.WriteLock()) { if (log.IsDebugEnabled()) @@ -461,13 +471,13 @@ public bool AfterInsert(CacheKey key, object value, object version) log.Debug("Inserting: {0}", key); } - var lockValue = _cache.Lock(key); + var lockValue = cache.Lock(key); try { - ILockable lockable = (ILockable) Cache.Get(key); + ILockable lockable = (ILockable) cache.Get(key); if (lockable == null) { - Cache.Put(key, CachedItem.Create(value, Cache.NextTimestamp(), version)); + cache.Put(key, CachedItem.Create(value, cache.NextTimestamp(), version)); if (log.IsDebugEnabled()) { log.Debug("Inserted: {0}", key); @@ -481,7 +491,7 @@ public bool AfterInsert(CacheKey key, object value, object version) } finally { - _cache.Unlock(key, lockValue); + cache.Unlock(key, lockValue); } } } @@ -514,11 +524,5 @@ private bool IsUnlockable(ISoftLock clientLock, ILockable myLock) clientLock != null && ((CacheLock) clientLock).Id == ((CacheLock) myLock).Id; } - - private void CheckCache() - { - if (_cache == null || _isDestroyed) - throw new InvalidOperationException(_isDestroyed ? "The cache has already been destroyed" : "The concrete cache is not defined"); - } } } From dc15695e9ca783d08a475bbd0e51d3d3070478fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Delaporte?= <12201973+fredericDelaporte@users.noreply.github.com> Date: Thu, 24 Sep 2020 20:33:48 +0200 Subject: [PATCH 3/6] Remove a double check --- src/NHibernate/Async/Cache/ReadWriteCache.cs | 5 +++-- src/NHibernate/Cache/ReadWriteCache.cs | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/NHibernate/Async/Cache/ReadWriteCache.cs b/src/NHibernate/Async/Cache/ReadWriteCache.cs index a215f30d1e1..ce8ac6a7031 100644 --- a/src/NHibernate/Async/Cache/ReadWriteCache.cs +++ b/src/NHibernate/Async/Cache/ReadWriteCache.cs @@ -269,8 +269,9 @@ private Task DecrementLockAsync(object key, CacheLock @lock, CancellationToken c try { //decrement the lock - @lock.Unlock(InternalCache.NextTimestamp()); - return InternalCache.PutAsync(key, @lock, cancellationToken); + var cache = InternalCache; + @lock.Unlock(cache.NextTimestamp()); + return cache.PutAsync(key, @lock, cancellationToken); } catch (Exception ex) { diff --git a/src/NHibernate/Cache/ReadWriteCache.cs b/src/NHibernate/Cache/ReadWriteCache.cs index 3a0af63a2ab..326e842e96a 100644 --- a/src/NHibernate/Cache/ReadWriteCache.cs +++ b/src/NHibernate/Cache/ReadWriteCache.cs @@ -344,8 +344,9 @@ public bool Put(CacheKey key, object value, long txTimestamp, object version, IC private void DecrementLock(object key, CacheLock @lock) { //decrement the lock - @lock.Unlock(InternalCache.NextTimestamp()); - InternalCache.Put(key, @lock); + var cache = InternalCache; + @lock.Unlock(cache.NextTimestamp()); + cache.Put(key, @lock); } public void Release(CacheKey key, ISoftLock clientLock) From ca5a6477d7cc8af5f5c48e0dd42b4df1b4187145 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Delaporte?= <12201973+fredericdelaporte@users.noreply.github.com> Date: Sun, 4 Oct 2020 16:12:58 +0200 Subject: [PATCH 4/6] Remove unused setter --- src/NHibernate/Cache/NonstrictReadWriteCache.cs | 1 - src/NHibernate/Cache/ReadOnlyCache.cs | 1 - src/NHibernate/Cache/ReadWriteCache.cs | 1 - 3 files changed, 3 deletions(-) diff --git a/src/NHibernate/Cache/NonstrictReadWriteCache.cs b/src/NHibernate/Cache/NonstrictReadWriteCache.cs index ec5a70f0fb6..e67b35dfe24 100644 --- a/src/NHibernate/Cache/NonstrictReadWriteCache.cs +++ b/src/NHibernate/Cache/NonstrictReadWriteCache.cs @@ -47,7 +47,6 @@ private CacheBase InternalCache throw new InvalidOperationException(_isDestroyed ? "The cache has already been destroyed" : "The concrete cache is not defined"); return _cache; } - set => _cache = value; } // 6.0 TODO: remove diff --git a/src/NHibernate/Cache/ReadOnlyCache.cs b/src/NHibernate/Cache/ReadOnlyCache.cs index 7fbbc1fcfd5..ceba37dccee 100644 --- a/src/NHibernate/Cache/ReadOnlyCache.cs +++ b/src/NHibernate/Cache/ReadOnlyCache.cs @@ -42,7 +42,6 @@ private CacheBase InternalCache throw new InvalidOperationException(_isDestroyed ? "The cache has already been destroyed" : "The concrete cache is not defined"); return _cache; } - set => _cache = value; } // 6.0 TODO: remove diff --git a/src/NHibernate/Cache/ReadWriteCache.cs b/src/NHibernate/Cache/ReadWriteCache.cs index 326e842e96a..aa6fc8e290e 100644 --- a/src/NHibernate/Cache/ReadWriteCache.cs +++ b/src/NHibernate/Cache/ReadWriteCache.cs @@ -66,7 +66,6 @@ private CacheBase InternalCache throw new InvalidOperationException(_isDestroyed ? "The cache has already been destroyed" : "The concrete cache is not defined"); return _cache; } - set => _cache = value; } // 6.0 TODO: remove From e2889f73502a9acfe1484494a2a64b6bc865a23a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Delaporte?= <12201973+fredericdelaporte@users.noreply.github.com> Date: Sun, 4 Oct 2020 16:26:57 +0200 Subject: [PATCH 5/6] Remove InternalCache --- .../Async/Cache/NonstrictReadWriteCache.cs | 16 +++---- src/NHibernate/Async/Cache/ReadOnlyCache.cs | 12 ++--- src/NHibernate/Async/Cache/ReadWriteCache.cs | 24 +++++----- .../Cache/NonstrictReadWriteCache.cs | 36 ++++++++------- src/NHibernate/Cache/ReadOnlyCache.cs | 32 ++++++++------ src/NHibernate/Cache/ReadWriteCache.cs | 44 ++++++++++--------- 6 files changed, 88 insertions(+), 76 deletions(-) diff --git a/src/NHibernate/Async/Cache/NonstrictReadWriteCache.cs b/src/NHibernate/Async/Cache/NonstrictReadWriteCache.cs index bd8fe846c02..f369d8a8898 100644 --- a/src/NHibernate/Async/Cache/NonstrictReadWriteCache.cs +++ b/src/NHibernate/Async/Cache/NonstrictReadWriteCache.cs @@ -32,7 +32,7 @@ public async Task GetAsync(CacheKey key, long txTimestamp, CancellationT log.Debug("Cache lookup: {0}", key); } - var result = await (InternalCache.GetAsync(key, cancellationToken)).ConfigureAwait(false); + var result = await (_this.Cache.GetAsync(key, cancellationToken)).ConfigureAwait(false); if (log.IsDebugEnabled()) { log.Debug(result != null ? "Cache hit: {0}" : "Cache miss: {0}", key); @@ -49,7 +49,7 @@ public async Task GetManyAsync(CacheKey[] keys, long timestamp, Cancel log.Debug("Cache lookup: {0}", string.Join(",", keys.AsEnumerable())); } - var results = await (InternalCache.GetManyAsync(keys, cancellationToken)).ConfigureAwait(false); + var results = await (_this.Cache.GetManyAsync(keys, cancellationToken)).ConfigureAwait(false); if (log.IsDebugEnabled()) { log.Debug("Cache hit: {0}", string.Join(",", keys.Where((k, i) => results != null))); @@ -85,7 +85,7 @@ public async Task PutManyAsync( } } - var cache = InternalCache; + var cache = _this.Cache; var skipKeyIndexes = new HashSet(); if (checkKeys.Any()) { @@ -138,7 +138,7 @@ public async Task PutAsync(CacheKey key, object value, long txTimestamp, o return false; } - var cache = InternalCache; + var cache = _this.Cache; if (minimalPut && await (cache.GetAsync(key, cancellationToken)).ConfigureAwait(false) != null) { if (log.IsDebugEnabled()) @@ -186,7 +186,7 @@ public Task RemoveAsync(CacheKey key, CancellationToken cancellationToken) { log.Debug("Removing: {0}", key); } - return InternalCache.RemoveAsync(key, cancellationToken); + return _this.Cache.RemoveAsync(key, cancellationToken); } catch (Exception ex) { @@ -206,7 +206,7 @@ public Task ClearAsync(CancellationToken cancellationToken) { log.Debug("Clearing"); } - return InternalCache.ClearAsync(cancellationToken); + return _this.Cache.ClearAsync(cancellationToken); } catch (Exception ex) { @@ -229,7 +229,7 @@ public Task EvictAsync(CacheKey key, CancellationToken cancellationToken) { log.Debug("Invalidating: {0}", key); } - return InternalCache.RemoveAsync(key, cancellationToken); + return _this.Cache.RemoveAsync(key, cancellationToken); } catch (Exception ex) { @@ -263,7 +263,7 @@ public Task ReleaseAsync(CacheKey key, ISoftLock @lock, CancellationToken cancel log.Debug("Invalidating (again): {0}", key); } - return InternalCache.RemoveAsync(key, cancellationToken); + return _this.Cache.RemoveAsync(key, cancellationToken); } catch (Exception ex) { diff --git a/src/NHibernate/Async/Cache/ReadOnlyCache.cs b/src/NHibernate/Async/Cache/ReadOnlyCache.cs index 65610093cea..e1fcabbf4f0 100644 --- a/src/NHibernate/Async/Cache/ReadOnlyCache.cs +++ b/src/NHibernate/Async/Cache/ReadOnlyCache.cs @@ -24,7 +24,7 @@ public partial class ReadOnlyCache : IBatchableCacheConcurrencyStrategy public async Task GetAsync(CacheKey key, long timestamp, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); - var result = await (InternalCache.GetAsync(key, cancellationToken)).ConfigureAwait(false); + var result = await (_this.Cache.GetAsync(key, cancellationToken)).ConfigureAwait(false); if (log.IsDebugEnabled()) { log.Debug(result != null ? "Cache hit: {0}" : "Cache miss: {0}", key); @@ -41,7 +41,7 @@ public async Task GetManyAsync(CacheKey[] keys, long timestamp, Cancel log.Debug("Cache lookup: {0}", string.Join(",", keys.AsEnumerable())); } - var results = await (InternalCache.GetManyAsync(keys, cancellationToken)).ConfigureAwait(false); + var results = await (_this.Cache.GetManyAsync(keys, cancellationToken)).ConfigureAwait(false); if (log.IsDebugEnabled()) { log.Debug("Cache hit: {0}", string.Join(",", keys.Where((k, i) => results[i] != null))); @@ -93,7 +93,7 @@ public async Task PutManyAsync( } } - var cache = InternalCache; + var cache = _this.Cache; var skipKeyIndexes = new HashSet(); if (checkKeys.Any()) { @@ -143,7 +143,7 @@ public async Task PutAsync(CacheKey key, object value, long timestamp, obj return false; } - var cache = InternalCache; + var cache = _this.Cache; if (minimalPut && await (cache.GetAsync(key, cancellationToken)).ConfigureAwait(false) != null) { if (log.IsDebugEnabled()) @@ -186,7 +186,7 @@ public Task ClearAsync(CancellationToken cancellationToken) { return Task.FromCanceled(cancellationToken); } - return InternalCache.ClearAsync(cancellationToken); + return _this.Cache.ClearAsync(cancellationToken); } public Task RemoveAsync(CacheKey key, CancellationToken cancellationToken) @@ -195,7 +195,7 @@ public Task RemoveAsync(CacheKey key, CancellationToken cancellationToken) { return Task.FromCanceled(cancellationToken); } - return InternalCache.RemoveAsync(key, cancellationToken); + return _this.Cache.RemoveAsync(key, cancellationToken); } /// diff --git a/src/NHibernate/Async/Cache/ReadWriteCache.cs b/src/NHibernate/Async/Cache/ReadWriteCache.cs index ce8ac6a7031..332b0777da6 100644 --- a/src/NHibernate/Async/Cache/ReadWriteCache.cs +++ b/src/NHibernate/Async/Cache/ReadWriteCache.cs @@ -42,7 +42,7 @@ public partial class ReadWriteCache : IBatchableCacheConcurrencyStrategy public async Task GetAsync(CacheKey key, long txTimestamp, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); - var cache = InternalCache; + var cache = _this.Cache; cancellationToken.ThrowIfCancellationRequested(); using (await (_asyncReaderWriterLock.ReadLockAsync()).ConfigureAwait(false)) { @@ -72,7 +72,7 @@ public async Task GetManyAsync(CacheKey[] keys, long timestamp, Cancel { log.Debug("Cache lookup: {0}", string.Join(",", keys.AsEnumerable())); } - var cache = InternalCache; + var cache = _this.Cache; var result = new object[keys.Length]; cancellationToken.ThrowIfCancellationRequested(); using (await (_asyncReaderWriterLock.ReadLockAsync()).ConfigureAwait(false)) @@ -97,7 +97,7 @@ public async Task GetManyAsync(CacheKey[] keys, long timestamp, Cancel public async Task LockAsync(CacheKey key, object version, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); - var cache = InternalCache; + var cache = _this.Cache; cancellationToken.ThrowIfCancellationRequested(); using (await (_asyncReaderWriterLock.WriteLockAsync()).ConfigureAwait(false)) { @@ -143,7 +143,7 @@ public async Task PutManyAsync( return result; } - var cache = InternalCache; + var cache = _this.Cache; cancellationToken.ThrowIfCancellationRequested(); using (await (_asyncReaderWriterLock.WriteLockAsync()).ConfigureAwait(false)) { @@ -215,7 +215,7 @@ public async Task PutAsync(CacheKey key, object value, long txTimestamp, o return false; } - var cache = InternalCache; + var cache = _this.Cache; cancellationToken.ThrowIfCancellationRequested(); using (await (_asyncReaderWriterLock.WriteLockAsync()).ConfigureAwait(false)) { @@ -269,7 +269,7 @@ private Task DecrementLockAsync(object key, CacheLock @lock, CancellationToken c try { //decrement the lock - var cache = InternalCache; + var cache = _this.Cache; @lock.Unlock(cache.NextTimestamp()); return cache.PutAsync(key, @lock, cancellationToken); } @@ -282,7 +282,7 @@ private Task DecrementLockAsync(object key, CacheLock @lock, CancellationToken c public async Task ReleaseAsync(CacheKey key, ISoftLock clientLock, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); - var cache = InternalCache; + var cache = _this.Cache; cancellationToken.ThrowIfCancellationRequested(); using (await (_asyncReaderWriterLock.WriteLockAsync()).ConfigureAwait(false)) { @@ -320,7 +320,7 @@ internal Task HandleLockExpiryAsync(object key, CancellationToken cancellationTo try { log.Warn("An item was expired by the cache while it was locked (increase your cache timeout): {0}", key); - var cache = InternalCache; + var cache = _this.Cache; long ts = cache.NextTimestamp() + cache.Timeout; // create new lock that times out immediately CacheLock @lock = CacheLock.Create(ts, NextLockId(), null); @@ -339,7 +339,7 @@ public Task ClearAsync(CancellationToken cancellationToken) { return Task.FromCanceled(cancellationToken); } - return InternalCache.ClearAsync(cancellationToken); + return _this.Cache.ClearAsync(cancellationToken); } public Task RemoveAsync(CacheKey key, CancellationToken cancellationToken) @@ -348,7 +348,7 @@ public Task RemoveAsync(CacheKey key, CancellationToken cancellationToken) { return Task.FromCanceled(cancellationToken); } - return InternalCache.RemoveAsync(key, cancellationToken); + return _this.Cache.RemoveAsync(key, cancellationToken); } /// @@ -358,7 +358,7 @@ public Task RemoveAsync(CacheKey key, CancellationToken cancellationToken) public async Task AfterUpdateAsync(CacheKey key, object value, object version, ISoftLock clientLock, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); - var cache = InternalCache; + var cache = _this.Cache; cancellationToken.ThrowIfCancellationRequested(); using (await (_asyncReaderWriterLock.WriteLockAsync()).ConfigureAwait(false)) { @@ -407,7 +407,7 @@ public async Task AfterUpdateAsync(CacheKey key, object value, object vers public async Task AfterInsertAsync(CacheKey key, object value, object version, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); - var cache = InternalCache; + var cache = _this.Cache; cancellationToken.ThrowIfCancellationRequested(); using (await (_asyncReaderWriterLock.WriteLockAsync()).ConfigureAwait(false)) { diff --git a/src/NHibernate/Cache/NonstrictReadWriteCache.cs b/src/NHibernate/Cache/NonstrictReadWriteCache.cs index e67b35dfe24..b4fe2464398 100644 --- a/src/NHibernate/Cache/NonstrictReadWriteCache.cs +++ b/src/NHibernate/Cache/NonstrictReadWriteCache.cs @@ -18,9 +18,19 @@ public partial class NonstrictReadWriteCache : IBatchableCacheConcurrencyStrateg { private static readonly INHibernateLogger log = NHibernateLogger.For(typeof(NonstrictReadWriteCache)); + // 6.0 TODO : remove + private readonly IBatchableCacheConcurrencyStrategy _this; private CacheBase _cache; private bool _isDestroyed; + /// + /// Default constructor. + /// + public NonstrictReadWriteCache() + { + _this = this; + } + /// /// Gets the cache region name. /// @@ -38,8 +48,8 @@ public ICache Cache set { _cache = value?.AsCacheBase(); } } - // 6.0 TODO: Rename to Cache and make public (possible breaking change for reader when null). - private CacheBase InternalCache + // 6.0 TODO: implement implicitly + CacheBase IBatchableCacheConcurrencyStrategy.Cache { get { @@ -47,12 +57,6 @@ private CacheBase InternalCache throw new InvalidOperationException(_isDestroyed ? "The cache has already been destroyed" : "The concrete cache is not defined"); return _cache; } - } - - // 6.0 TODO: remove - CacheBase IBatchableCacheConcurrencyStrategy.Cache - { - get => _cache; set => _cache = value; } @@ -66,7 +70,7 @@ public object Get(CacheKey key, long txTimestamp) log.Debug("Cache lookup: {0}", key); } - var result = InternalCache.Get(key); + var result = _this.Cache.Get(key); if (log.IsDebugEnabled()) { log.Debug(result != null ? "Cache hit: {0}" : "Cache miss: {0}", key); @@ -82,7 +86,7 @@ public object[] GetMany(CacheKey[] keys, long timestamp) log.Debug("Cache lookup: {0}", string.Join(",", keys.AsEnumerable())); } - var results = InternalCache.GetMany(keys); + var results = _this.Cache.GetMany(keys); if (log.IsDebugEnabled()) { log.Debug("Cache hit: {0}", string.Join(",", keys.Where((k, i) => results != null))); @@ -117,7 +121,7 @@ public bool[] PutMany( } } - var cache = InternalCache; + var cache = _this.Cache; var skipKeyIndexes = new HashSet(); if (checkKeys.Any()) { @@ -169,7 +173,7 @@ public bool Put(CacheKey key, object value, long txTimestamp, object version, IC return false; } - var cache = InternalCache; + var cache = _this.Cache; if (minimalPut && cache.Get(key) != null) { if (log.IsDebugEnabled()) @@ -200,7 +204,7 @@ public void Remove(CacheKey key) { log.Debug("Removing: {0}", key); } - InternalCache.Remove(key); + _this.Cache.Remove(key); } public void Clear() @@ -209,7 +213,7 @@ public void Clear() { log.Debug("Clearing"); } - InternalCache.Clear(); + _this.Cache.Clear(); } public void Destroy() @@ -229,7 +233,7 @@ public void Evict(CacheKey key) { log.Debug("Invalidating: {0}", key); } - InternalCache.Remove(key); + _this.Cache.Remove(key); } /// @@ -259,7 +263,7 @@ public void Release(CacheKey key, ISoftLock @lock) log.Debug("Invalidating (again): {0}", key); } - InternalCache.Remove(key); + _this.Cache.Remove(key); } /// diff --git a/src/NHibernate/Cache/ReadOnlyCache.cs b/src/NHibernate/Cache/ReadOnlyCache.cs index ceba37dccee..0fabc9751de 100644 --- a/src/NHibernate/Cache/ReadOnlyCache.cs +++ b/src/NHibernate/Cache/ReadOnlyCache.cs @@ -13,9 +13,19 @@ public partial class ReadOnlyCache : IBatchableCacheConcurrencyStrategy { private static readonly INHibernateLogger log = NHibernateLogger.For(typeof(ReadOnlyCache)); + // 6.0 TODO : remove + private readonly IBatchableCacheConcurrencyStrategy _this; private CacheBase _cache; private bool _isDestroyed; + /// + /// Default constructor. + /// + public ReadOnlyCache() + { + _this = this; + } + /// /// Gets the cache region name. /// @@ -33,8 +43,8 @@ public ICache Cache set { _cache = value?.AsCacheBase(); } } - // 6.0 TODO: Rename to Cache and make public (possible breaking change for reader when null). - private CacheBase InternalCache + // 6.0 TODO: implement implicitly + CacheBase IBatchableCacheConcurrencyStrategy.Cache { get { @@ -42,18 +52,12 @@ private CacheBase InternalCache throw new InvalidOperationException(_isDestroyed ? "The cache has already been destroyed" : "The concrete cache is not defined"); return _cache; } - } - - // 6.0 TODO: remove - CacheBase IBatchableCacheConcurrencyStrategy.Cache - { - get => _cache; set => _cache = value; } public object Get(CacheKey key, long timestamp) { - var result = InternalCache.Get(key); + var result = _this.Cache.Get(key); if (log.IsDebugEnabled()) { log.Debug(result != null ? "Cache hit: {0}" : "Cache miss: {0}", key); @@ -69,7 +73,7 @@ public object[] GetMany(CacheKey[] keys, long timestamp) log.Debug("Cache lookup: {0}", string.Join(",", keys.AsEnumerable())); } - var results = InternalCache.GetMany(keys); + var results = _this.Cache.GetMany(keys); if (log.IsDebugEnabled()) { log.Debug("Cache hit: {0}", string.Join(",", keys.Where((k, i) => results[i] != null))); @@ -110,7 +114,7 @@ public bool[] PutMany( } } - var cache = InternalCache; + var cache = _this.Cache; var skipKeyIndexes = new HashSet(); if (checkKeys.Any()) { @@ -159,7 +163,7 @@ public bool Put(CacheKey key, object value, long timestamp, object version, ICom return false; } - var cache = InternalCache; + var cache = _this.Cache; if (minimalPut && cache.Get(key) != null) { if (log.IsDebugEnabled()) @@ -186,12 +190,12 @@ public void Release(CacheKey key, ISoftLock @lock) public void Clear() { - InternalCache.Clear(); + _this.Cache.Clear(); } public void Remove(CacheKey key) { - InternalCache.Remove(key); + _this.Cache.Remove(key); } public void Destroy() diff --git a/src/NHibernate/Cache/ReadWriteCache.cs b/src/NHibernate/Cache/ReadWriteCache.cs index aa6fc8e290e..078c011ead8 100644 --- a/src/NHibernate/Cache/ReadWriteCache.cs +++ b/src/NHibernate/Cache/ReadWriteCache.cs @@ -35,11 +35,21 @@ public interface ILockable private static readonly INHibernateLogger log = NHibernateLogger.For(typeof(ReadWriteCache)); + // 6.0 TODO : remove + private readonly IBatchableCacheConcurrencyStrategy _this; private CacheBase _cache; private bool _isDestroyed; private int _nextLockId; private readonly AsyncReaderWriterLock _asyncReaderWriterLock = new AsyncReaderWriterLock(); + /// + /// Default constructor. + /// + public ReadWriteCache() + { + _this = this; + } + /// /// Gets the cache region name. /// @@ -57,8 +67,8 @@ public ICache Cache set { _cache = value?.AsCacheBase(); } } - // 6.0 TODO: Rename to Cache and make public (possible breaking change for reader when null). - private CacheBase InternalCache + // 6.0 TODO: implement implicitly + CacheBase IBatchableCacheConcurrencyStrategy.Cache { get { @@ -66,12 +76,6 @@ private CacheBase InternalCache throw new InvalidOperationException(_isDestroyed ? "The cache has already been destroyed" : "The concrete cache is not defined"); return _cache; } - } - - // 6.0 TODO: remove - CacheBase IBatchableCacheConcurrencyStrategy.Cache - { - get => _cache; set => _cache = value; } @@ -109,7 +113,7 @@ private int NextLockId() /// public object Get(CacheKey key, long txTimestamp) { - var cache = InternalCache; + var cache = _this.Cache; using (_asyncReaderWriterLock.ReadLock()) { if (log.IsDebugEnabled()) @@ -137,7 +141,7 @@ public object[] GetMany(CacheKey[] keys, long timestamp) { log.Debug("Cache lookup: {0}", string.Join(",", keys.AsEnumerable())); } - var cache = InternalCache; + var cache = _this.Cache; var result = new object[keys.Length]; using (_asyncReaderWriterLock.ReadLock()) { @@ -182,7 +186,7 @@ private static object GetValue(long timestamp, CacheKey key, ILockable lockable) /// public ISoftLock Lock(CacheKey key, object version) { - var cache = InternalCache; + var cache = _this.Cache; using (_asyncReaderWriterLock.WriteLock()) { if (log.IsDebugEnabled()) @@ -226,7 +230,7 @@ public bool[] PutMany( return result; } - var cache = InternalCache; + var cache = _this.Cache; using (_asyncReaderWriterLock.WriteLock()) { if (log.IsDebugEnabled()) @@ -296,7 +300,7 @@ public bool Put(CacheKey key, object value, long txTimestamp, object version, IC return false; } - var cache = InternalCache; + var cache = _this.Cache; using (_asyncReaderWriterLock.WriteLock()) { if (log.IsDebugEnabled()) @@ -343,14 +347,14 @@ public bool Put(CacheKey key, object value, long txTimestamp, object version, IC private void DecrementLock(object key, CacheLock @lock) { //decrement the lock - var cache = InternalCache; + var cache = _this.Cache; @lock.Unlock(cache.NextTimestamp()); cache.Put(key, @lock); } public void Release(CacheKey key, ISoftLock clientLock) { - var cache = InternalCache; + var cache = _this.Cache; using (_asyncReaderWriterLock.WriteLock()) { if (log.IsDebugEnabled()) @@ -381,7 +385,7 @@ public void Release(CacheKey key, ISoftLock clientLock) internal void HandleLockExpiry(object key) { log.Warn("An item was expired by the cache while it was locked (increase your cache timeout): {0}", key); - var cache = InternalCache; + var cache = _this.Cache; long ts = cache.NextTimestamp() + cache.Timeout; // create new lock that times out immediately CacheLock @lock = CacheLock.Create(ts, NextLockId(), null); @@ -391,12 +395,12 @@ internal void HandleLockExpiry(object key) public void Clear() { - InternalCache.Clear(); + _this.Cache.Clear(); } public void Remove(CacheKey key) { - InternalCache.Remove(key); + _this.Cache.Remove(key); } public void Destroy() @@ -416,7 +420,7 @@ public void Destroy() /// public bool AfterUpdate(CacheKey key, object value, object version, ISoftLock clientLock) { - var cache = InternalCache; + var cache = _this.Cache; using (_asyncReaderWriterLock.WriteLock()) { if (log.IsDebugEnabled()) @@ -463,7 +467,7 @@ public bool AfterUpdate(CacheKey key, object value, object version, ISoftLock cl public bool AfterInsert(CacheKey key, object value, object version) { - var cache = InternalCache; + var cache = _this.Cache; using (_asyncReaderWriterLock.WriteLock()) { if (log.IsDebugEnabled()) From 3cc8ee49522682be0978d377525703fcffbc343f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Delaporte?= <12201973+fredericDelaporte@users.noreply.github.com> Date: Wed, 7 Oct 2020 21:04:08 +0200 Subject: [PATCH 6/6] Revert "Remove InternalCache" This reverts commit e2889f73502a9acfe1484494a2a64b6bc865a23a. --- .../Async/Cache/NonstrictReadWriteCache.cs | 16 +++---- src/NHibernate/Async/Cache/ReadOnlyCache.cs | 12 ++--- src/NHibernate/Async/Cache/ReadWriteCache.cs | 24 +++++----- .../Cache/NonstrictReadWriteCache.cs | 36 +++++++-------- src/NHibernate/Cache/ReadOnlyCache.cs | 32 ++++++-------- src/NHibernate/Cache/ReadWriteCache.cs | 44 +++++++++---------- 6 files changed, 76 insertions(+), 88 deletions(-) diff --git a/src/NHibernate/Async/Cache/NonstrictReadWriteCache.cs b/src/NHibernate/Async/Cache/NonstrictReadWriteCache.cs index f369d8a8898..bd8fe846c02 100644 --- a/src/NHibernate/Async/Cache/NonstrictReadWriteCache.cs +++ b/src/NHibernate/Async/Cache/NonstrictReadWriteCache.cs @@ -32,7 +32,7 @@ public async Task GetAsync(CacheKey key, long txTimestamp, CancellationT log.Debug("Cache lookup: {0}", key); } - var result = await (_this.Cache.GetAsync(key, cancellationToken)).ConfigureAwait(false); + var result = await (InternalCache.GetAsync(key, cancellationToken)).ConfigureAwait(false); if (log.IsDebugEnabled()) { log.Debug(result != null ? "Cache hit: {0}" : "Cache miss: {0}", key); @@ -49,7 +49,7 @@ public async Task GetManyAsync(CacheKey[] keys, long timestamp, Cancel log.Debug("Cache lookup: {0}", string.Join(",", keys.AsEnumerable())); } - var results = await (_this.Cache.GetManyAsync(keys, cancellationToken)).ConfigureAwait(false); + var results = await (InternalCache.GetManyAsync(keys, cancellationToken)).ConfigureAwait(false); if (log.IsDebugEnabled()) { log.Debug("Cache hit: {0}", string.Join(",", keys.Where((k, i) => results != null))); @@ -85,7 +85,7 @@ public async Task PutManyAsync( } } - var cache = _this.Cache; + var cache = InternalCache; var skipKeyIndexes = new HashSet(); if (checkKeys.Any()) { @@ -138,7 +138,7 @@ public async Task PutAsync(CacheKey key, object value, long txTimestamp, o return false; } - var cache = _this.Cache; + var cache = InternalCache; if (minimalPut && await (cache.GetAsync(key, cancellationToken)).ConfigureAwait(false) != null) { if (log.IsDebugEnabled()) @@ -186,7 +186,7 @@ public Task RemoveAsync(CacheKey key, CancellationToken cancellationToken) { log.Debug("Removing: {0}", key); } - return _this.Cache.RemoveAsync(key, cancellationToken); + return InternalCache.RemoveAsync(key, cancellationToken); } catch (Exception ex) { @@ -206,7 +206,7 @@ public Task ClearAsync(CancellationToken cancellationToken) { log.Debug("Clearing"); } - return _this.Cache.ClearAsync(cancellationToken); + return InternalCache.ClearAsync(cancellationToken); } catch (Exception ex) { @@ -229,7 +229,7 @@ public Task EvictAsync(CacheKey key, CancellationToken cancellationToken) { log.Debug("Invalidating: {0}", key); } - return _this.Cache.RemoveAsync(key, cancellationToken); + return InternalCache.RemoveAsync(key, cancellationToken); } catch (Exception ex) { @@ -263,7 +263,7 @@ public Task ReleaseAsync(CacheKey key, ISoftLock @lock, CancellationToken cancel log.Debug("Invalidating (again): {0}", key); } - return _this.Cache.RemoveAsync(key, cancellationToken); + return InternalCache.RemoveAsync(key, cancellationToken); } catch (Exception ex) { diff --git a/src/NHibernate/Async/Cache/ReadOnlyCache.cs b/src/NHibernate/Async/Cache/ReadOnlyCache.cs index e1fcabbf4f0..65610093cea 100644 --- a/src/NHibernate/Async/Cache/ReadOnlyCache.cs +++ b/src/NHibernate/Async/Cache/ReadOnlyCache.cs @@ -24,7 +24,7 @@ public partial class ReadOnlyCache : IBatchableCacheConcurrencyStrategy public async Task GetAsync(CacheKey key, long timestamp, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); - var result = await (_this.Cache.GetAsync(key, cancellationToken)).ConfigureAwait(false); + var result = await (InternalCache.GetAsync(key, cancellationToken)).ConfigureAwait(false); if (log.IsDebugEnabled()) { log.Debug(result != null ? "Cache hit: {0}" : "Cache miss: {0}", key); @@ -41,7 +41,7 @@ public async Task GetManyAsync(CacheKey[] keys, long timestamp, Cancel log.Debug("Cache lookup: {0}", string.Join(",", keys.AsEnumerable())); } - var results = await (_this.Cache.GetManyAsync(keys, cancellationToken)).ConfigureAwait(false); + var results = await (InternalCache.GetManyAsync(keys, cancellationToken)).ConfigureAwait(false); if (log.IsDebugEnabled()) { log.Debug("Cache hit: {0}", string.Join(",", keys.Where((k, i) => results[i] != null))); @@ -93,7 +93,7 @@ public async Task PutManyAsync( } } - var cache = _this.Cache; + var cache = InternalCache; var skipKeyIndexes = new HashSet(); if (checkKeys.Any()) { @@ -143,7 +143,7 @@ public async Task PutAsync(CacheKey key, object value, long timestamp, obj return false; } - var cache = _this.Cache; + var cache = InternalCache; if (minimalPut && await (cache.GetAsync(key, cancellationToken)).ConfigureAwait(false) != null) { if (log.IsDebugEnabled()) @@ -186,7 +186,7 @@ public Task ClearAsync(CancellationToken cancellationToken) { return Task.FromCanceled(cancellationToken); } - return _this.Cache.ClearAsync(cancellationToken); + return InternalCache.ClearAsync(cancellationToken); } public Task RemoveAsync(CacheKey key, CancellationToken cancellationToken) @@ -195,7 +195,7 @@ public Task RemoveAsync(CacheKey key, CancellationToken cancellationToken) { return Task.FromCanceled(cancellationToken); } - return _this.Cache.RemoveAsync(key, cancellationToken); + return InternalCache.RemoveAsync(key, cancellationToken); } /// diff --git a/src/NHibernate/Async/Cache/ReadWriteCache.cs b/src/NHibernate/Async/Cache/ReadWriteCache.cs index 332b0777da6..ce8ac6a7031 100644 --- a/src/NHibernate/Async/Cache/ReadWriteCache.cs +++ b/src/NHibernate/Async/Cache/ReadWriteCache.cs @@ -42,7 +42,7 @@ public partial class ReadWriteCache : IBatchableCacheConcurrencyStrategy public async Task GetAsync(CacheKey key, long txTimestamp, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); - var cache = _this.Cache; + var cache = InternalCache; cancellationToken.ThrowIfCancellationRequested(); using (await (_asyncReaderWriterLock.ReadLockAsync()).ConfigureAwait(false)) { @@ -72,7 +72,7 @@ public async Task GetManyAsync(CacheKey[] keys, long timestamp, Cancel { log.Debug("Cache lookup: {0}", string.Join(",", keys.AsEnumerable())); } - var cache = _this.Cache; + var cache = InternalCache; var result = new object[keys.Length]; cancellationToken.ThrowIfCancellationRequested(); using (await (_asyncReaderWriterLock.ReadLockAsync()).ConfigureAwait(false)) @@ -97,7 +97,7 @@ public async Task GetManyAsync(CacheKey[] keys, long timestamp, Cancel public async Task LockAsync(CacheKey key, object version, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); - var cache = _this.Cache; + var cache = InternalCache; cancellationToken.ThrowIfCancellationRequested(); using (await (_asyncReaderWriterLock.WriteLockAsync()).ConfigureAwait(false)) { @@ -143,7 +143,7 @@ public async Task PutManyAsync( return result; } - var cache = _this.Cache; + var cache = InternalCache; cancellationToken.ThrowIfCancellationRequested(); using (await (_asyncReaderWriterLock.WriteLockAsync()).ConfigureAwait(false)) { @@ -215,7 +215,7 @@ public async Task PutAsync(CacheKey key, object value, long txTimestamp, o return false; } - var cache = _this.Cache; + var cache = InternalCache; cancellationToken.ThrowIfCancellationRequested(); using (await (_asyncReaderWriterLock.WriteLockAsync()).ConfigureAwait(false)) { @@ -269,7 +269,7 @@ private Task DecrementLockAsync(object key, CacheLock @lock, CancellationToken c try { //decrement the lock - var cache = _this.Cache; + var cache = InternalCache; @lock.Unlock(cache.NextTimestamp()); return cache.PutAsync(key, @lock, cancellationToken); } @@ -282,7 +282,7 @@ private Task DecrementLockAsync(object key, CacheLock @lock, CancellationToken c public async Task ReleaseAsync(CacheKey key, ISoftLock clientLock, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); - var cache = _this.Cache; + var cache = InternalCache; cancellationToken.ThrowIfCancellationRequested(); using (await (_asyncReaderWriterLock.WriteLockAsync()).ConfigureAwait(false)) { @@ -320,7 +320,7 @@ internal Task HandleLockExpiryAsync(object key, CancellationToken cancellationTo try { log.Warn("An item was expired by the cache while it was locked (increase your cache timeout): {0}", key); - var cache = _this.Cache; + var cache = InternalCache; long ts = cache.NextTimestamp() + cache.Timeout; // create new lock that times out immediately CacheLock @lock = CacheLock.Create(ts, NextLockId(), null); @@ -339,7 +339,7 @@ public Task ClearAsync(CancellationToken cancellationToken) { return Task.FromCanceled(cancellationToken); } - return _this.Cache.ClearAsync(cancellationToken); + return InternalCache.ClearAsync(cancellationToken); } public Task RemoveAsync(CacheKey key, CancellationToken cancellationToken) @@ -348,7 +348,7 @@ public Task RemoveAsync(CacheKey key, CancellationToken cancellationToken) { return Task.FromCanceled(cancellationToken); } - return _this.Cache.RemoveAsync(key, cancellationToken); + return InternalCache.RemoveAsync(key, cancellationToken); } /// @@ -358,7 +358,7 @@ public Task RemoveAsync(CacheKey key, CancellationToken cancellationToken) public async Task AfterUpdateAsync(CacheKey key, object value, object version, ISoftLock clientLock, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); - var cache = _this.Cache; + var cache = InternalCache; cancellationToken.ThrowIfCancellationRequested(); using (await (_asyncReaderWriterLock.WriteLockAsync()).ConfigureAwait(false)) { @@ -407,7 +407,7 @@ public async Task AfterUpdateAsync(CacheKey key, object value, object vers public async Task AfterInsertAsync(CacheKey key, object value, object version, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); - var cache = _this.Cache; + var cache = InternalCache; cancellationToken.ThrowIfCancellationRequested(); using (await (_asyncReaderWriterLock.WriteLockAsync()).ConfigureAwait(false)) { diff --git a/src/NHibernate/Cache/NonstrictReadWriteCache.cs b/src/NHibernate/Cache/NonstrictReadWriteCache.cs index b4fe2464398..e67b35dfe24 100644 --- a/src/NHibernate/Cache/NonstrictReadWriteCache.cs +++ b/src/NHibernate/Cache/NonstrictReadWriteCache.cs @@ -18,19 +18,9 @@ public partial class NonstrictReadWriteCache : IBatchableCacheConcurrencyStrateg { private static readonly INHibernateLogger log = NHibernateLogger.For(typeof(NonstrictReadWriteCache)); - // 6.0 TODO : remove - private readonly IBatchableCacheConcurrencyStrategy _this; private CacheBase _cache; private bool _isDestroyed; - /// - /// Default constructor. - /// - public NonstrictReadWriteCache() - { - _this = this; - } - /// /// Gets the cache region name. /// @@ -48,8 +38,8 @@ public ICache Cache set { _cache = value?.AsCacheBase(); } } - // 6.0 TODO: implement implicitly - CacheBase IBatchableCacheConcurrencyStrategy.Cache + // 6.0 TODO: Rename to Cache and make public (possible breaking change for reader when null). + private CacheBase InternalCache { get { @@ -57,6 +47,12 @@ CacheBase IBatchableCacheConcurrencyStrategy.Cache throw new InvalidOperationException(_isDestroyed ? "The cache has already been destroyed" : "The concrete cache is not defined"); return _cache; } + } + + // 6.0 TODO: remove + CacheBase IBatchableCacheConcurrencyStrategy.Cache + { + get => _cache; set => _cache = value; } @@ -70,7 +66,7 @@ public object Get(CacheKey key, long txTimestamp) log.Debug("Cache lookup: {0}", key); } - var result = _this.Cache.Get(key); + var result = InternalCache.Get(key); if (log.IsDebugEnabled()) { log.Debug(result != null ? "Cache hit: {0}" : "Cache miss: {0}", key); @@ -86,7 +82,7 @@ public object[] GetMany(CacheKey[] keys, long timestamp) log.Debug("Cache lookup: {0}", string.Join(",", keys.AsEnumerable())); } - var results = _this.Cache.GetMany(keys); + var results = InternalCache.GetMany(keys); if (log.IsDebugEnabled()) { log.Debug("Cache hit: {0}", string.Join(",", keys.Where((k, i) => results != null))); @@ -121,7 +117,7 @@ public bool[] PutMany( } } - var cache = _this.Cache; + var cache = InternalCache; var skipKeyIndexes = new HashSet(); if (checkKeys.Any()) { @@ -173,7 +169,7 @@ public bool Put(CacheKey key, object value, long txTimestamp, object version, IC return false; } - var cache = _this.Cache; + var cache = InternalCache; if (minimalPut && cache.Get(key) != null) { if (log.IsDebugEnabled()) @@ -204,7 +200,7 @@ public void Remove(CacheKey key) { log.Debug("Removing: {0}", key); } - _this.Cache.Remove(key); + InternalCache.Remove(key); } public void Clear() @@ -213,7 +209,7 @@ public void Clear() { log.Debug("Clearing"); } - _this.Cache.Clear(); + InternalCache.Clear(); } public void Destroy() @@ -233,7 +229,7 @@ public void Evict(CacheKey key) { log.Debug("Invalidating: {0}", key); } - _this.Cache.Remove(key); + InternalCache.Remove(key); } /// @@ -263,7 +259,7 @@ public void Release(CacheKey key, ISoftLock @lock) log.Debug("Invalidating (again): {0}", key); } - _this.Cache.Remove(key); + InternalCache.Remove(key); } /// diff --git a/src/NHibernate/Cache/ReadOnlyCache.cs b/src/NHibernate/Cache/ReadOnlyCache.cs index 0fabc9751de..ceba37dccee 100644 --- a/src/NHibernate/Cache/ReadOnlyCache.cs +++ b/src/NHibernate/Cache/ReadOnlyCache.cs @@ -13,19 +13,9 @@ public partial class ReadOnlyCache : IBatchableCacheConcurrencyStrategy { private static readonly INHibernateLogger log = NHibernateLogger.For(typeof(ReadOnlyCache)); - // 6.0 TODO : remove - private readonly IBatchableCacheConcurrencyStrategy _this; private CacheBase _cache; private bool _isDestroyed; - /// - /// Default constructor. - /// - public ReadOnlyCache() - { - _this = this; - } - /// /// Gets the cache region name. /// @@ -43,8 +33,8 @@ public ICache Cache set { _cache = value?.AsCacheBase(); } } - // 6.0 TODO: implement implicitly - CacheBase IBatchableCacheConcurrencyStrategy.Cache + // 6.0 TODO: Rename to Cache and make public (possible breaking change for reader when null). + private CacheBase InternalCache { get { @@ -52,12 +42,18 @@ CacheBase IBatchableCacheConcurrencyStrategy.Cache throw new InvalidOperationException(_isDestroyed ? "The cache has already been destroyed" : "The concrete cache is not defined"); return _cache; } + } + + // 6.0 TODO: remove + CacheBase IBatchableCacheConcurrencyStrategy.Cache + { + get => _cache; set => _cache = value; } public object Get(CacheKey key, long timestamp) { - var result = _this.Cache.Get(key); + var result = InternalCache.Get(key); if (log.IsDebugEnabled()) { log.Debug(result != null ? "Cache hit: {0}" : "Cache miss: {0}", key); @@ -73,7 +69,7 @@ public object[] GetMany(CacheKey[] keys, long timestamp) log.Debug("Cache lookup: {0}", string.Join(",", keys.AsEnumerable())); } - var results = _this.Cache.GetMany(keys); + var results = InternalCache.GetMany(keys); if (log.IsDebugEnabled()) { log.Debug("Cache hit: {0}", string.Join(",", keys.Where((k, i) => results[i] != null))); @@ -114,7 +110,7 @@ public bool[] PutMany( } } - var cache = _this.Cache; + var cache = InternalCache; var skipKeyIndexes = new HashSet(); if (checkKeys.Any()) { @@ -163,7 +159,7 @@ public bool Put(CacheKey key, object value, long timestamp, object version, ICom return false; } - var cache = _this.Cache; + var cache = InternalCache; if (minimalPut && cache.Get(key) != null) { if (log.IsDebugEnabled()) @@ -190,12 +186,12 @@ public void Release(CacheKey key, ISoftLock @lock) public void Clear() { - _this.Cache.Clear(); + InternalCache.Clear(); } public void Remove(CacheKey key) { - _this.Cache.Remove(key); + InternalCache.Remove(key); } public void Destroy() diff --git a/src/NHibernate/Cache/ReadWriteCache.cs b/src/NHibernate/Cache/ReadWriteCache.cs index 078c011ead8..aa6fc8e290e 100644 --- a/src/NHibernate/Cache/ReadWriteCache.cs +++ b/src/NHibernate/Cache/ReadWriteCache.cs @@ -35,21 +35,11 @@ public interface ILockable private static readonly INHibernateLogger log = NHibernateLogger.For(typeof(ReadWriteCache)); - // 6.0 TODO : remove - private readonly IBatchableCacheConcurrencyStrategy _this; private CacheBase _cache; private bool _isDestroyed; private int _nextLockId; private readonly AsyncReaderWriterLock _asyncReaderWriterLock = new AsyncReaderWriterLock(); - /// - /// Default constructor. - /// - public ReadWriteCache() - { - _this = this; - } - /// /// Gets the cache region name. /// @@ -67,8 +57,8 @@ public ICache Cache set { _cache = value?.AsCacheBase(); } } - // 6.0 TODO: implement implicitly - CacheBase IBatchableCacheConcurrencyStrategy.Cache + // 6.0 TODO: Rename to Cache and make public (possible breaking change for reader when null). + private CacheBase InternalCache { get { @@ -76,6 +66,12 @@ CacheBase IBatchableCacheConcurrencyStrategy.Cache throw new InvalidOperationException(_isDestroyed ? "The cache has already been destroyed" : "The concrete cache is not defined"); return _cache; } + } + + // 6.0 TODO: remove + CacheBase IBatchableCacheConcurrencyStrategy.Cache + { + get => _cache; set => _cache = value; } @@ -113,7 +109,7 @@ private int NextLockId() /// public object Get(CacheKey key, long txTimestamp) { - var cache = _this.Cache; + var cache = InternalCache; using (_asyncReaderWriterLock.ReadLock()) { if (log.IsDebugEnabled()) @@ -141,7 +137,7 @@ public object[] GetMany(CacheKey[] keys, long timestamp) { log.Debug("Cache lookup: {0}", string.Join(",", keys.AsEnumerable())); } - var cache = _this.Cache; + var cache = InternalCache; var result = new object[keys.Length]; using (_asyncReaderWriterLock.ReadLock()) { @@ -186,7 +182,7 @@ private static object GetValue(long timestamp, CacheKey key, ILockable lockable) /// public ISoftLock Lock(CacheKey key, object version) { - var cache = _this.Cache; + var cache = InternalCache; using (_asyncReaderWriterLock.WriteLock()) { if (log.IsDebugEnabled()) @@ -230,7 +226,7 @@ public bool[] PutMany( return result; } - var cache = _this.Cache; + var cache = InternalCache; using (_asyncReaderWriterLock.WriteLock()) { if (log.IsDebugEnabled()) @@ -300,7 +296,7 @@ public bool Put(CacheKey key, object value, long txTimestamp, object version, IC return false; } - var cache = _this.Cache; + var cache = InternalCache; using (_asyncReaderWriterLock.WriteLock()) { if (log.IsDebugEnabled()) @@ -347,14 +343,14 @@ public bool Put(CacheKey key, object value, long txTimestamp, object version, IC private void DecrementLock(object key, CacheLock @lock) { //decrement the lock - var cache = _this.Cache; + var cache = InternalCache; @lock.Unlock(cache.NextTimestamp()); cache.Put(key, @lock); } public void Release(CacheKey key, ISoftLock clientLock) { - var cache = _this.Cache; + var cache = InternalCache; using (_asyncReaderWriterLock.WriteLock()) { if (log.IsDebugEnabled()) @@ -385,7 +381,7 @@ public void Release(CacheKey key, ISoftLock clientLock) internal void HandleLockExpiry(object key) { log.Warn("An item was expired by the cache while it was locked (increase your cache timeout): {0}", key); - var cache = _this.Cache; + var cache = InternalCache; long ts = cache.NextTimestamp() + cache.Timeout; // create new lock that times out immediately CacheLock @lock = CacheLock.Create(ts, NextLockId(), null); @@ -395,12 +391,12 @@ internal void HandleLockExpiry(object key) public void Clear() { - _this.Cache.Clear(); + InternalCache.Clear(); } public void Remove(CacheKey key) { - _this.Cache.Remove(key); + InternalCache.Remove(key); } public void Destroy() @@ -420,7 +416,7 @@ public void Destroy() /// public bool AfterUpdate(CacheKey key, object value, object version, ISoftLock clientLock) { - var cache = _this.Cache; + var cache = InternalCache; using (_asyncReaderWriterLock.WriteLock()) { if (log.IsDebugEnabled()) @@ -467,7 +463,7 @@ public bool AfterUpdate(CacheKey key, object value, object version, ISoftLock cl public bool AfterInsert(CacheKey key, object value, object version) { - var cache = _this.Cache; + var cache = InternalCache; using (_asyncReaderWriterLock.WriteLock()) { if (log.IsDebugEnabled())