Created
November 7, 2017 08:20
-
-
Save dawoe/f8d649c09f4f6341ea9630acbab44cf0 to your computer and use it in GitHub Desktop.
Donut Cache examples from Umbraco UK Festival talk "The need for speed"
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class DefaultController : RenderMvcController | |
{ | |
[UmbracoDonutOutputCache(CacheProfile = "LongPageCache", | |
Options = OutputCacheOptions.NoCacheLookupForPosts & | |
OutputCacheOptions.ReplaceDonutsInChildActions, Order = 100)] | |
public override ActionResult Index(RenderModel model) | |
{ | |
return base.Index(model); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Global : UmbracoApplication | |
{ | |
public override string GetVaryByCustomString(HttpContext context, string custom) | |
{ | |
var result = base.GetVaryByCustomString(context, custom); | |
if (string.IsNullOrEmpty(custom)) | |
{ | |
return result; | |
} | |
if (UmbracoContext.Current.IsFrontEndUmbracoRequest) | |
{ | |
var keys = custom.Split(new[] { ";" }).ToList(); | |
if (keys.Contains("url")) | |
{ | |
result += $"pageid={UmbracoContext.Current.PageId};"; | |
result += $"url={context.Request.Url}"; | |
} | |
} | |
return result; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class UmbracoDonutOutputCacheAttribute : DonutOutputCacheAttribute | |
{ | |
public override void OnActionExecuting(ActionExecutingContext filterContext) | |
{ | |
// overrides donut output cache attribute to not cache when in umbraco preview mode or Doctype grid editor preview | |
this.Duration = -1; | |
var previewMode = UmbracoContext.Current.InPreviewMode; | |
if (!previewMode) | |
{ | |
if (UmbracoContext.Current.HttpContext.Request.QueryString["dtgePreview"] == "1") | |
{ | |
previewMode = true; | |
} | |
} | |
if (previewMode) | |
{ | |
this.Duration = 0; | |
} | |
base.OnActionExecuting(filterContext); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class UmbracoStartup : ApplicationEventHandler | |
{ | |
protected override void ApplicationStarting(UmbracoApplicationBase umbracoApplication, | |
ApplicationContext applicationContext) | |
{ | |
DefaultRenderMvcControllerResolver.Current. | |
SetDefaultControllerType(typeof(DefaultController)); | |
PageCacheRefresher.CacheUpdated += this.PageCacheRefresherCacheUpdated; | |
} | |
private void PageCacheRefresherCacheUpdated(PageCacheRefresher sender, CacheRefresherEventArgs e) | |
{ | |
switch (e.MessageType) | |
{ | |
case MessageType.RefreshById: | |
case MessageType.RemoveById: | |
var contentId = (int)e.MessageObject; | |
var doctype = string.Empty; | |
var item = UmbracoContext.Current.ContentCache.GetById(contentId); | |
if (item != null) | |
{ | |
doctype = item.DocumentTypeAlias; | |
} | |
this.ClearPageOutputCache(contentId, doctype); | |
break; | |
case MessageType.RefreshByInstance: | |
case MessageType.RemoveByInstance: | |
var content = e.MessageObject as IContent; | |
if (content == null) | |
{ | |
return; | |
} | |
this.ClearPageOutputCache(content.Id, content.ContentType.Alias); | |
break; | |
} | |
} | |
private void ClearPageOutputCache(int contentId, string doctype) | |
{ | |
var enumerableCache = OutputCache.Instance as IEnumerable<KeyValuePair<string, object>>; | |
if (enumerableCache == null) | |
{ | |
return; | |
} | |
// get all output cache keys that contain current page id | |
var keysToDelete = enumerableCache | |
.Where(x => !string.IsNullOrEmpty(x.Key) && x.Key.Contains($"pageid={contentId};")) | |
.Select(x => x.Key); | |
// remove all caches for current page | |
foreach (var key in keysToDelete) | |
{ | |
OutputCache.Instance.Remove(key); | |
} | |
var manager = new OutputCacheManager(); | |
manager.RemoveItems("MasterSurface","Footer"); | |
if(doctype == "NewsDetail") | |
{ | |
// clear cache of all news related actions | |
manager.RemoveItems("NewsSurface"); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<system.web> | |
<caching> | |
<outputCache enableOutputCache="true" /> | |
<outputCacheSettings> | |
<outputCacheProfiles> | |
<add name="LongGlobalCache" duration="86400" /> | |
<add name="LongPageCache" duration="86400" varyByCustom="url" /> | |
<add name="LongUserPageCache" duration="86400" varyByCustom="url;user" /> | |
<add name="NoCache" duration="0" /> | |
</outputCacheProfiles> | |
</outputCacheSettings> | |
</caching> | |
</system.web> |
How will you cache the header and footer in this scenario? Do u add a custom cache attribute with a different profile on them?
varyByCustom="url;user"
can cause cause problems when parsing cache keys as ;
is the default delimiter for any other MVC routes that will also be stored in the key.
This will create a key that looks like this: url;user=pageid=1;url=/your-url;somethingelse=somethingelse;
etc.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is great Dave thanks, it'll make a big difference for how I handle caching. One thing - I'm finding that IsFrontEndUmbracoRequest is returning true even if the request comes from opening the node in the backoffice. Do you see the same?