Reinoud van Dalen

November 14, 2014

Add sliding expiration on Sitecore Rendering cache

There have been a number of times where setting an expiration date on a renderings html cache would have been the right thing for me to do. I wasn’t able then but I have found a way now.

Tried modifying the cache key

Once I fixed this by adding DateTime.Now.Hour to the cache key so a components htmlcache would only be valid for one hour. You could try to make this behavior more complicated, add an expiration date to the key and somehow parse that before you regenerate a new key, but that was not a quick fix.

Wait what? Sitecore has a hidden Timeout

Allowing resharper to decompile sources while navigating is a blessing because I learned that Sitecore already has a Timeout property hidden in RenderingCachingDefenition. If we were somehow able to set this property then Sitecore will handle the rest.

Now I’m not sure why the property is there because I haven’t found a way to give it a value other than injecting it myself using a custom field. Maybe someone knows the answer to that, I will start a tread on sdn after my post for this.

Edit: I found this arcticle which seems to imply that the functions are there to be set programatically. So I guess this is the right move if you want to set the timeout in Sitecore.

How quaint and obsolete, let’s modify!

Kudos for those who know in what cartoon series that phrase is used. As I said, injecting a Timeout seems the only solution to me and that’s exactly what I’ll tell you. For this you need to:

Add a Timeout field to Sitecore’s Caching template

Add timeout field on caching template

Pretty straight forward, nothing much to add to this. Next we need to:

Override the AddRecordedHtmlToCache processor

This processor is responsible for adding the html output to the site’s html cache container. Conveniently we only need to override the GetTimeout method (Thank you Sitecore for making this method virtual) and TryParse our custom fields value like so:

public class AddRecordedHtmlToCache : Sitecore.Mvc.Pipelines.Response.RenderRendering.AddRecordedHtmlToCache
{
protected override TimeSpan GetTimeout(RenderRenderingArgs args)
{
TimeSpan result;
return TimeSpan.TryParse(args.Rendering.RenderingItem.InnerItem["Timeout"], out result) ? result : TimeSpan.Zero;
}
}

Put it to the test

To test this a picked a ControllerRendering and set the Timeout to ‘0:0:10’, this should result in a valid cache for 10 seconds. I had set a breakpoint in the controller action and hit the refresh button in my browser. The first time the breakpoint got hit but in the next 10 seconds it would not get hit if I refreshed the page. 

Problem solved! We’re now able to set an expiration date on a components cache.

TAGS: sitecore cache


Comments
Ruud van Falier

Very nice find, Reinoud! It's a shame that we have to implement it ourselves though.. I found that it's also possible to set a default sliding expiration for all renderings with a configuration setting. Caching.HtmlLifetime = "01:00:00" Cheers!


Jim Noellsch

Super helpful, indeed! I ended up adding a processor right before AddRecordedHtmlToCache that just modifies the args.Renderings.Caching.Timeout property.