/// <summary> /// Writes a token cache blob to the serialization cache (identified by its key). /// </summary> /// <param name="cacheKey">Token cache key.</param> /// <param name="bytes">Bytes to write.</param> /// <param name="cacheSerializerHints">Hints for the cache serialization implementation optimization.</param> /// <returns>A <see cref="Task"/> that completes when a write operation has completed.</returns> protected override Task WriteCacheBytesAsync( string cacheKey, byte[] bytes, CacheSerializerHints cacheSerializerHints) { TimeSpan?cacheExpiry = null; if (cacheSerializerHints != null && cacheSerializerHints?.SuggestedCacheExpiry != null) { cacheExpiry = cacheSerializerHints.SuggestedCacheExpiry.Value.UtcDateTime - DateTime.UtcNow; if (cacheExpiry < TimeSpan.Zero) { cacheExpiry = TimeSpan.FromMilliseconds(1); } } MemoryCacheEntryOptions memoryCacheEntryOptions = new MemoryCacheEntryOptions() { AbsoluteExpirationRelativeToNow = cacheExpiry ?? _cacheOptions.AbsoluteExpirationRelativeToNow, Size = bytes?.Length, }; _memoryCache.Set(cacheKey, bytes, memoryCacheEntryOptions); return(Task.CompletedTask); }
/// <summary> /// Read a blob representing the token cache from its key. /// </summary> /// <param name="cacheKey">Key representing the token cache /// (account or app).</param> /// <param name="cacheSerializerHints">Hints for the cache serialization implementation optimization.</param> /// <returns>Read blob.</returns> protected override async Task <byte[]> ReadCacheBytesAsync(string cacheKey, CacheSerializerHints cacheSerializerHints) { #pragma warning disable CA1062 // Validate arguments of public methods await _session.LoadAsync(cacheSerializerHints.CancellationToken).ConfigureAwait(false); #pragma warning restore CA1062 // Validate arguments of public methods _sessionLock.EnterReadLock(); try { if (_session.TryGetValue(cacheKey, out byte[] blob))
/// <summary> /// Removes a specific token cache, described by its cache key /// from the distributed cache. /// </summary> /// <param name="cacheKey">Key of the cache to remove.</param> /// <param name="cacheSerializerHints">Hints for the cache serialization implementation optimization.</param> /// <returns>A <see cref="Task"/> that completes when key removal has completed.</returns> protected override async Task RemoveKeyAsync(string cacheKey, CacheSerializerHints cacheSerializerHints) { const string remove = "Remove"; if (_memoryCache != null) { _memoryCache.Remove(cacheKey); Logger.MemoryCacheRemove(_logger, _memoryCacheType, remove, cacheKey, null); } await L2OperationWithRetryOnFailureAsync( remove, (cacheKey) => _distributedCache.RemoveAsync(cacheKey, cacheSerializerHints.CancellationToken), cacheKey).ConfigureAwait(false); }
private async Task CreateL1L2TestWithSerializerHints( System.DateTimeOffset dateTimeOffset, int memoryCacheExpectedCount) { // Arrange byte[] cache = new byte[3]; AssertCacheValues(_testCacheAdapter); Assert.Equal(0, _testCacheAdapter._memoryCache.Count); Assert.Empty(L2Cache._dict); CacheSerializerHints cacheSerializerHints = new CacheSerializerHints(); cacheSerializerHints.SuggestedCacheExpiry = dateTimeOffset; // Act TestDistributedCache.ResetEvent.Reset(); await _testCacheAdapter.TestWriteCacheBytesAsync(DefaultCacheKey, cache, cacheSerializerHints).ConfigureAwait(false); // Assert Assert.Equal(memoryCacheExpectedCount, _testCacheAdapter._memoryCache.Count); TestDistributedCache.ResetEvent.Wait(); Assert.Single(L2Cache._dict); }
/// <summary> /// Writes a token cache blob to the serialization cache (by key). /// </summary> /// <param name="cacheKey">Cache key.</param> /// <param name="bytes">blob to write.</param> /// <param name="cacheSerializerHints">Hints for the cache serialization implementation optimization.</param> /// <returns>A <see cref="Task"/> that completes when a write operation has completed.</returns> protected override async Task WriteCacheBytesAsync( string cacheKey, byte[] bytes, CacheSerializerHints cacheSerializerHints) { const string write = "Write"; DateTimeOffset?cacheExpiry = cacheSerializerHints?.SuggestedCacheExpiry; if (_memoryCache != null) { MemoryCacheEntryOptions memoryCacheEntryOptions = new MemoryCacheEntryOptions() { AbsoluteExpiration = cacheExpiry ?? _distributedCacheOptions.AbsoluteExpiration, AbsoluteExpirationRelativeToNow = _expirationTime, Size = bytes?.Length, }; // write in both _memoryCache.Set(cacheKey, bytes, memoryCacheEntryOptions); Logger.MemoryCacheRead(_logger, _memoryCacheType, write, cacheKey, bytes?.Length ?? 0, null); Logger.MemoryCacheCount(_logger, _memoryCacheType, write, _memoryCache.Count, null); } if ((cacheExpiry != null && _distributedCacheOptions.AbsoluteExpiration != null && _distributedCacheOptions.AbsoluteExpiration < cacheExpiry) || (cacheExpiry == null && _distributedCacheOptions.AbsoluteExpiration != null)) { cacheExpiry = _distributedCacheOptions.AbsoluteExpiration; } DistributedCacheEntryOptions distributedCacheEntryOptions = new DistributedCacheEntryOptions() { AbsoluteExpiration = cacheExpiry, AbsoluteExpirationRelativeToNow = _distributedCacheOptions.AbsoluteExpirationRelativeToNow, SlidingExpiration = _distributedCacheOptions.SlidingExpiration, }; if (_distributedCacheOptions.DisableL1Cache || !_distributedCacheOptions.EnableAsyncL2Write) { await L2OperationWithRetryOnFailureAsync( write, (cacheKey) => _distributedCache.SetAsync( cacheKey, bytes, distributedCacheEntryOptions, cacheSerializerHints?.CancellationToken ?? CancellationToken.None), cacheKey).Measure().ConfigureAwait(false); } else { _ = Task.Run(async() => await L2OperationWithRetryOnFailureAsync( write, (cacheKey) => _distributedCache.SetAsync( cacheKey, bytes, distributedCacheEntryOptions, cacheSerializerHints?.CancellationToken ?? CancellationToken.None), cacheKey).Measure().ConfigureAwait(false)); } }
/// <summary> /// Read a specific token cache, described by its cache key, from the /// distributed cache. /// </summary> /// <param name="cacheKey">Key of the cache item to retrieve.</param> /// <param name="cacheSerializerHints">Hints for the cache serialization implementation optimization.</param> /// <returns>Read blob representing a token cache for the cache key /// (account or app).</returns> protected override async Task <byte[]> ReadCacheBytesAsync(string cacheKey, CacheSerializerHints cacheSerializerHints) { const string read = "Read"; byte[]? result = null; if (_memoryCache != null) { // check memory cache first result = (byte[])_memoryCache.Get(cacheKey); Logger.MemoryCacheRead(_logger, _memoryCacheType, read, cacheKey, result?.Length ?? 0, null); } if (result == null) { var measure = await Task.Run( async() => { // not found in memory, check distributed cache result = await L2OperationWithRetryOnFailureAsync( read, (cacheKey) => _distributedCache.GetAsync(cacheKey, cacheSerializerHints.CancellationToken), cacheKey).ConfigureAwait(false); #pragma warning disable CA1062 // Validate arguments of public methods }, cacheSerializerHints.CancellationToken).Measure().ConfigureAwait(false); #pragma warning restore CA1062 // Validate arguments of public methods Logger.DistributedCacheReadTime(_logger, _distributedCacheType, read, measure.MilliSeconds, null); if (_memoryCache != null) { // back propagate to memory cache if (result != null) { MemoryCacheEntryOptions memoryCacheEntryOptions = new MemoryCacheEntryOptions() { AbsoluteExpirationRelativeToNow = _expirationTime, Size = result?.Length, }; Logger.BackPropagateL2toL1(_logger, memoryCacheEntryOptions.Size ?? 0, null); _memoryCache.Set(cacheKey, result, memoryCacheEntryOptions); Logger.MemoryCacheCount(_logger, _memoryCacheType, read, _memoryCache.Count, null); } } } else { await L2OperationWithRetryOnFailureAsync( "Refresh", (cacheKey) => _distributedCache.RefreshAsync(cacheKey, cacheSerializerHints.CancellationToken), cacheKey, result !).ConfigureAwait(false); } #pragma warning disable CS8603 // Possible null reference return. return(result); #pragma warning restore CS8603 // Possible null reference return. }
public async Task TestWriteCacheBytesAsync(string cacheKey, byte[] bytes, CacheSerializerHints cacheSerializerHints = null) { await WriteCacheBytesAsync(cacheKey, bytes, cacheSerializerHints).ConfigureAwait(false); }