private async Task SetCachedValueAsync(string cacheKey, string value, CacheContext context)
        {
            var failover = _memoryCache.Get <bool>(FailoverKey);

            if (failover)
            {
                return;
            }

            var bytes = Encoding.UTF8.GetBytes(value);

            var options = new DistributedCacheEntryOptions
            {
                AbsoluteExpiration = context.ExpiresOn,
                SlidingExpiration  = context.ExpiresSliding,
                AbsoluteExpirationRelativeToNow = context.ExpiresAfter
            };

            // Default duration is sliding expiration (permanent as long as it's used)
            if (!options.AbsoluteExpiration.HasValue && !options.SlidingExpiration.HasValue && !options.AbsoluteExpirationRelativeToNow.HasValue)
            {
                options.SlidingExpiration = new TimeSpan(0, 1, 0);
            }

            try
            {
                await _dynamicCache.SetAsync(cacheKey, bytes, options);
            }
            catch (Exception e)
            {
                _logger.LogError(e, "Failed to write the '{CacheKey}' to the dynamic cache", cacheKey);

                _memoryCache.Set(FailoverKey, true, new MemoryCacheEntryOptions()
                {
                    AbsoluteExpirationRelativeToNow = _dynamicCacheOptions.FailoverRetryLatency
                });

                return;
            }

            // Lazy load to prevent cyclic dependency
            _tagcache ??= _serviceProvider.GetRequiredService <ITagCache>();
            await _tagcache.TagAsync(cacheKey, context.Tags.ToArray());
        }
        private async Task SetCachedValueAsync(string cacheKey, string value, CacheContext context)
        {
            var bytes = Encoding.UTF8.GetBytes(value);

            var options = new DistributedCacheEntryOptions
            {
                AbsoluteExpiration = context.ExpiresOn,
                SlidingExpiration  = context.ExpiresSliding,
                AbsoluteExpirationRelativeToNow = context.ExpiresAfter
            };

            // Default duration is sliding expiration (permanent as long as it's used)
            if (!options.AbsoluteExpiration.HasValue && !options.SlidingExpiration.HasValue && !options.AbsoluteExpirationRelativeToNow.HasValue)
            {
                options.SlidingExpiration = new TimeSpan(0, 1, 0);
            }

            await _dynamicCache.SetAsync(cacheKey, bytes, options);

            // Lazy load to prevent cyclic dependency
            _tagcache ??= _serviceProvider.GetRequiredService <ITagCache>();
            await _tagcache.TagAsync(cacheKey, context.Tags.ToArray());
        }