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; } } }
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); } } }