Browse Source

Replace TryGetValue/TryRemove by a single TryRemove call to avoid potential issues with concurrent cache removal/addition

pull/2236/head
Kévin Chalet 7 years ago
parent
commit
b834c048a8
  1. 22
      src/OpenIddict.Core/Caches/OpenIddictApplicationCache.cs
  2. 22
      src/OpenIddict.Core/Caches/OpenIddictAuthorizationCache.cs
  3. 22
      src/OpenIddict.Core/Caches/OpenIddictScopeCache.cs
  4. 22
      src/OpenIddict.Core/Caches/OpenIddictTokenCache.cs

22
src/OpenIddict.Core/Caches/OpenIddictApplicationCache.cs

@ -24,7 +24,7 @@ namespace OpenIddict.Core
public class OpenIddictApplicationCache<TApplication> : IOpenIddictApplicationCache<TApplication>, IDisposable where TApplication : class
{
private readonly MemoryCache _cache;
private readonly ConcurrentDictionary<string, Lazy<CancellationTokenSource>> _signals;
private readonly ConcurrentDictionary<string, CancellationTokenSource> _signals;
private readonly IOpenIddictApplicationStore<TApplication> _store;
public OpenIddictApplicationCache(
@ -36,7 +36,7 @@ namespace OpenIddict.Core
SizeLimit = options.CurrentValue.EntityCacheLimit
});
_signals = new ConcurrentDictionary<string, Lazy<CancellationTokenSource>>(StringComparer.Ordinal);
_signals = new ConcurrentDictionary<string, CancellationTokenSource>(StringComparer.Ordinal);
_store = resolver.Get<TApplication>();
}
@ -121,7 +121,7 @@ namespace OpenIddict.Core
{
foreach (var signal in _signals)
{
signal.Value.Value.Dispose();
signal.Value.Dispose();
}
_cache.Dispose();
@ -378,11 +378,9 @@ namespace OpenIddict.Core
throw new InvalidOperationException("The application identifier cannot be extracted.");
}
if (_signals.TryGetValue(identifier, out Lazy<CancellationTokenSource> signal))
if (_signals.TryRemove(identifier, out CancellationTokenSource signal))
{
signal.Value.Cancel();
_signals.TryRemove(identifier, out signal);
signal.Cancel();
}
}
@ -410,15 +408,9 @@ namespace OpenIddict.Core
throw new InvalidOperationException("The application identifier cannot be extracted.");
}
var signal = _signals.GetOrAdd(identifier, delegate
{
// Note: a Lazy<CancellationTokenSource> is used here to ensure only one CancellationTokenSource
// can be created. Not doing so would result in expiration signals being potentially linked to
// multiple sources, with a single one of them being eventually tracked and thus, cancelable.
return new Lazy<CancellationTokenSource>(() => new CancellationTokenSource());
});
var signal = _signals.GetOrAdd(identifier, _ => new CancellationTokenSource());
return new CancellationChangeToken(signal.Value.Token);
return new CancellationChangeToken(signal.Token);
}
}
}

22
src/OpenIddict.Core/Caches/OpenIddictAuthorizationCache.cs

@ -24,7 +24,7 @@ namespace OpenIddict.Core
public class OpenIddictAuthorizationCache<TAuthorization> : IOpenIddictAuthorizationCache<TAuthorization>, IDisposable where TAuthorization : class
{
private readonly MemoryCache _cache;
private readonly ConcurrentDictionary<string, Lazy<CancellationTokenSource>> _signals;
private readonly ConcurrentDictionary<string, CancellationTokenSource> _signals;
private readonly IOpenIddictAuthorizationStore<TAuthorization> _store;
public OpenIddictAuthorizationCache(
@ -36,7 +36,7 @@ namespace OpenIddict.Core
SizeLimit = options.CurrentValue.EntityCacheLimit
});
_signals = new ConcurrentDictionary<string, Lazy<CancellationTokenSource>>(StringComparer.Ordinal);
_signals = new ConcurrentDictionary<string, CancellationTokenSource>(StringComparer.Ordinal);
_store = resolver.Get<TAuthorization>();
}
@ -122,7 +122,7 @@ namespace OpenIddict.Core
{
foreach (var signal in _signals)
{
signal.Value.Value.Dispose();
signal.Value.Dispose();
}
_cache.Dispose();
@ -596,11 +596,9 @@ namespace OpenIddict.Core
throw new InvalidOperationException("The application identifier cannot be extracted.");
}
if (_signals.TryGetValue(identifier, out Lazy<CancellationTokenSource> signal))
if (_signals.TryRemove(identifier, out CancellationTokenSource signal))
{
signal.Value.Cancel();
_signals.TryRemove(identifier, out signal);
signal.Cancel();
}
}
@ -628,15 +626,9 @@ namespace OpenIddict.Core
throw new InvalidOperationException("The authorization identifier cannot be extracted.");
}
var signal = _signals.GetOrAdd(identifier, delegate
{
// Note: a Lazy<CancellationTokenSource> is used here to ensure only one CancellationTokenSource
// can be created. Not doing so would result in expiration signals being potentially linked to
// multiple sources, with a single one of them being eventually tracked and thus, cancelable.
return new Lazy<CancellationTokenSource>(() => new CancellationTokenSource());
});
var signal = _signals.GetOrAdd(identifier, _ => new CancellationTokenSource());
return new CancellationChangeToken(signal.Value.Token);
return new CancellationChangeToken(signal.Token);
}
}
}

22
src/OpenIddict.Core/Caches/OpenIddictScopeCache.cs

@ -25,7 +25,7 @@ namespace OpenIddict.Core
public class OpenIddictScopeCache<TScope> : IOpenIddictScopeCache<TScope>, IDisposable where TScope : class
{
private readonly MemoryCache _cache;
private readonly ConcurrentDictionary<string, Lazy<CancellationTokenSource>> _signals;
private readonly ConcurrentDictionary<string, CancellationTokenSource> _signals;
private readonly IOpenIddictScopeStore<TScope> _store;
public OpenIddictScopeCache(
@ -37,7 +37,7 @@ namespace OpenIddict.Core
SizeLimit = options.CurrentValue.EntityCacheLimit
});
_signals = new ConcurrentDictionary<string, Lazy<CancellationTokenSource>>(StringComparer.Ordinal);
_signals = new ConcurrentDictionary<string, CancellationTokenSource>(StringComparer.Ordinal);
_store = resolver.Get<TScope>();
}
@ -113,7 +113,7 @@ namespace OpenIddict.Core
{
foreach (var signal in _signals)
{
signal.Value.Value.Dispose();
signal.Value.Dispose();
}
_cache.Dispose();
@ -349,11 +349,9 @@ namespace OpenIddict.Core
throw new InvalidOperationException("The application identifier cannot be extracted.");
}
if (_signals.TryGetValue(identifier, out Lazy<CancellationTokenSource> signal))
if (_signals.TryRemove(identifier, out CancellationTokenSource signal))
{
signal.Value.Cancel();
_signals.TryRemove(identifier, out signal);
signal.Cancel();
}
}
@ -380,15 +378,9 @@ namespace OpenIddict.Core
throw new InvalidOperationException("The scope identifier cannot be extracted.");
}
var signal = _signals.GetOrAdd(identifier, delegate
{
// Note: a Lazy<CancellationTokenSource> is used here to ensure only one CancellationTokenSource
// can be created. Not doing so would result in expiration signals being potentially linked to
// multiple sources, with a single one of them being eventually tracked and thus, cancelable.
return new Lazy<CancellationTokenSource>(() => new CancellationTokenSource());
});
var signal = _signals.GetOrAdd(identifier, _ => new CancellationTokenSource());
return new CancellationChangeToken(signal.Value.Token);
return new CancellationChangeToken(signal.Token);
}
}
}

22
src/OpenIddict.Core/Caches/OpenIddictTokenCache.cs

@ -24,7 +24,7 @@ namespace OpenIddict.Core
public class OpenIddictTokenCache<TToken> : IOpenIddictTokenCache<TToken>, IDisposable where TToken : class
{
private readonly MemoryCache _cache;
private readonly ConcurrentDictionary<string, Lazy<CancellationTokenSource>> _signals;
private readonly ConcurrentDictionary<string, CancellationTokenSource> _signals;
private readonly IOpenIddictTokenStore<TToken> _store;
public OpenIddictTokenCache(
@ -36,7 +36,7 @@ namespace OpenIddict.Core
SizeLimit = options.CurrentValue.EntityCacheLimit
});
_signals = new ConcurrentDictionary<string, Lazy<CancellationTokenSource>>(StringComparer.Ordinal);
_signals = new ConcurrentDictionary<string, CancellationTokenSource>(StringComparer.Ordinal);
_store = resolver.Get<TToken>();
}
@ -145,7 +145,7 @@ namespace OpenIddict.Core
{
foreach (var signal in _signals)
{
signal.Value.Value.Dispose();
signal.Value.Dispose();
}
_cache.Dispose();
@ -679,11 +679,9 @@ namespace OpenIddict.Core
throw new InvalidOperationException("The application identifier cannot be extracted.");
}
if (_signals.TryGetValue(identifier, out Lazy<CancellationTokenSource> signal))
if (_signals.TryRemove(identifier, out CancellationTokenSource signal))
{
signal.Value.Cancel();
_signals.TryRemove(identifier, out signal);
signal.Cancel();
}
}
@ -710,15 +708,9 @@ namespace OpenIddict.Core
throw new InvalidOperationException("The token identifier cannot be extracted.");
}
var signal = _signals.GetOrAdd(identifier, delegate
{
// Note: a Lazy<CancellationTokenSource> is used here to ensure only one CancellationTokenSource
// can be created. Not doing so would result in expiration signals being potentially linked to
// multiple sources, with a single one of them being eventually tracked and thus, cancelable.
return new Lazy<CancellationTokenSource>(() => new CancellationTokenSource());
});
var signal = _signals.GetOrAdd(identifier, _ => new CancellationTokenSource());
return new CancellationChangeToken(signal.Value.Token);
return new CancellationChangeToken(signal.Token);
}
}
}

Loading…
Cancel
Save