Пример #1
0
        /// <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))
Пример #3
0
        /// <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);
        }
Пример #5
0
        /// <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));
            }
        }
Пример #6
0
        /// <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);
 }