private void Invalidate(ItemLevelCachePart part)
        {
            InitializeSettings(part);

            foreach (var settings in part.ItemLevelCacheSettings)
            {
                var displayType = settings.Key;

                switch (settings.Value.InvalidationAction)
                {
                case ItemLevelCacheInvalidationAction.Evict:

                    mCacheService.RemoveByTag(ItemLevelCacheTag.For(part, displayType));
                    break;

                case ItemLevelCacheInvalidationAction.PreRender:

                    var shape = mContentManager.BuildDisplay(part.ContentItem, displayType);
                    shape.BypassDonutTokenization = true;

                    var markup    = (string)mShapeDisplay.Display(shape);
                    var cacheItem = new ItemLevelCacheItem(markup);

                    mCacheService.RemoveByTag(ItemLevelCacheTag.For(part, displayType));

                    // Give the markup to the item-level cache service which will cache it if required.
                    mItemLevelCacheService.CacheItem(part.ContentItem, displayType, cacheItem);
                    break;
                }
            }
        }
Exemplo n.º 2
0
        protected override DriverResult Editor(ItemLevelCachePart part, dynamic shapeHelper)
        {
            var driverResults = new List <DriverResult>();

            if (mAuthorizer.Authorize(ItemLevelCachePermissions.EditItemLevelCacheSettings))
            {
                driverResults.Add(ContentShape("Parts_ItemLevelCacheSettings_Edit", () => shapeHelper.EditorTemplate(TemplateName: "Parts/ItemLevelCacheSettings", Model: part, Prefix: Prefix)));
            }

            if (mAuthorizer.Authorize(ItemLevelCachePermissions.ViewItemLevelCacheItems))
            {
                driverResults.Add(ContentShape("Parts_ItemLevelCache_CacheItemsForContent", () =>
                {
                    var outputCacheItems = mOutputCacheStorageProvider.GetCacheItems(0, mOutputCacheStorageProvider.GetCacheItemsCount()).Where(i => i.Tags.Contains(ItemLevelCacheTag.For(part)));
                    var vm = new CacheItemsForContentViewModel()
                    {
                        UserCanEvict = mAuthorizer.Authorize(ItemLevelCachePermissions.EvictItemLevelCacheItems),
                        Tag          = ItemLevelCacheTag.For(part),
                        // TODO: Would it be more efficient to get all the cache keys using ITagCache, as opposed to getting all then filtering?
                        CacheItems = outputCacheItems.Select(ci => ci.ToCacheItemModel())
                    };

                    return(shapeHelper.EditorTemplate(TemplateName: "Parts/CacheItemsForContent", Model: vm, Prefix: Prefix));
                }));
            }

            return(Combined(driverResults.ToArray()));
        }
        public void CacheItem_CachedItemIsAsExpected(int cacheDuration, int graceDuration, string markup)
        {
            var displayType = "AlwaysMiss";

            var contentItem = ContentItem.WithPart(new ItemLevelCachePart(), "Article", 42);

            contentItem.As <ItemLevelCachePart>().ItemLevelCacheSettings[displayType] = new ItemLevelCacheSettings
            {
                Mode = ItemLevelCacheMode.CacheItem,
                CacheDurationSeconds  = cacheDuration,
                CacheGraceTimeSeconds = graceDuration
            };

            var cacheKey = mSut.GetCacheKey(contentItem, displayType);

            mSut.CacheItem(contentItem, displayType, new ItemLevelCacheItem(markup));

            var cachedItem = mCachedItems[cacheKey];

            Assert.AreEqual(cacheKey, cachedItem.CacheKey);
            Assert.AreEqual(cacheKey, cachedItem.InvariantCacheKey);

            Assert.AreEqual(cacheDuration, cachedItem.Duration);
            Assert.AreEqual(graceDuration, cachedItem.GraceTime);
            Assert.AreEqual(markup, mJsonConvertor.Deserialize <ItemLevelCacheItem>(Encoding.UTF8.GetString(cachedItem.Output)).Markup);
            Assert.AreEqual(mShellSettings.Name, cachedItem.Tenant);
            Assert.AreEqual(mClock.Object.UtcNow, cachedItem.CachedOnUtc);

            Assert.AreEqual(string.Empty, cachedItem.Url);

            Assert.Contains(ItemLevelCacheTag.For(contentItem), cachedItem.Tags);
            Assert.Contains(ItemLevelCacheTag.For(contentItem, displayType), cachedItem.Tags);
        }
        public void CacheItem(IContent contentItem, string displayType, ItemLevelCacheItem itemLevelCacheItem)
        {
            if (contentItem == null)
            {
                return;
            }

            var itemLevelCachePart = contentItem.As <ItemLevelCachePart>();

            if (itemLevelCachePart == null || !itemLevelCachePart.ItemLevelCacheSettings.ContainsKey(displayType) || itemLevelCachePart.ItemLevelCacheSettings[displayType].Mode != ItemLevelCacheMode.CacheItem)
            {
                return;
            }

            var settings = itemLevelCachePart.ItemLevelCacheSettings[displayType];
            var cacheKey = GetCacheKey(contentItem, displayType);

            var cachedItem = mOutputCacheStorageProvider.GetCacheItem(cacheKey);

            if (cachedItem == null || cachedItem.IsInGracePeriod(mClock.UtcNow)) // TODO: Should this method check the cache first, or just blindly insert?
            {
                var serializedCacheItem = mJsonConverter.Serialize(itemLevelCacheItem);

                var cacheItem = new CacheItem()
                {
                    CachedOnUtc = mClock.UtcNow,
                    Duration    = settings.CacheDurationSeconds,
                    GraceTime   = settings.CacheGraceTimeSeconds,
                    Output      = mHttpContextAccessor.Current().Request.ContentEncoding.GetBytes(serializedCacheItem),
                    Tags        = new[]
                    {
                        ItemLevelCacheTag.GenericTag,
                        ItemLevelCacheTag.For(contentItem),
                        ItemLevelCacheTag.For(contentItem, displayType),
                        ItemLevelCacheTag.For(contentItem.ContentItem.TypeDefinition)
                    },
                    Tenant            = mShellSettings.Name,
                    CacheKey          = cacheKey,
                    InvariantCacheKey = cacheKey,
                    Url = ""
                };

                mOutputCacheStorageProvider.Set(cacheKey, cacheItem);

                // Also add the item tags to the tag cache.
                foreach (var tag in cacheItem.Tags)
                {
                    mTagCache.Tag(tag, cacheKey);
                }
            }
        }