Sitecore custom cache that is cleared on publish

In this article I will demonstrate how to create a custom Sitecore cache and how to ensure that it is cleared when you publish.

First I will create the simplest custom cache available:

namespace MyNamespace
{
  public class MyCustomCache : CustomCache
  {
    public MyCustomCache(string name, long maxSize) : base("MyCustomCache." + name, maxSize)
    {
    }

    public string Get(string cacheKey)
    {
      return GetString(cacheKey);
    }

    public void Set(string cacheKey, string value)
    {
      SetString(cacheKey, value);
    }
  }
}

The cache is instantiated with a name, meaning that you can use the class to create more than one cache, as long as you remember to give each instance its own name.

The cache contains a string as key and returns a string as value. It is used like this (pseudocode):

// Instantiation, set up an 1MB cache
private MyCustomCache myCustomCache = new MyCustomCache("CacheName", StringUtil.ParseSizeString("1MB"));

// Get value from cache
string myValue = myCustomCache.Get(myKey);

// Set value in cache
myCustomCache.Set(myKey, myValue);
  

To clear the cache on publish, we need to set up an event handler on either publish:end and publish:end:remote or publish:complete and publish:complete:remote.

There is a little confusion as to when in the publish pipeline these events are fired. In previous versions (prior to Sitecore 7.2), publish:end and publish:end:remote was fired for each language and each target, and publish:complete and publish:complete:remote was fired when the publish job was done. But in later versions, publish:end and publish:end:remote is also only fired once.

The :remote events (publish:end:remote and publish:complete:remote) is fired on your remote (i.e. CD servers) by the way.

Enough talk, lets code the cache clearer. First I will set up the 2 new events on publish:end and publish:end:remote:

<events>
  <event name="publish:end">
    <handler type="MyNamespace.MyCacheClearer, Mydll" method="ClearCaches">
      <caches hint="list">
        <cache>MyCustomCache.CacheName</cache>
      </caches>
    </handler>
  </event>
  <event name="publish:end:remote">
    <handler type="MyNamespace.MyCacheClearer, Mydll" method="ClearCaches">
      <caches hint="list">
        <cache>MyCustomCache.CacheName</cache>
      </caches>
    </handler>
  </event>
</events>

The events will now call the method ClearCaches on the Mynamespace.MyCacheClearer class:

namespace MyNamespace
{
  public class MyCacheClearer 
  {
    public void ClearCaches(object sender, EventArgs args)
    {
      Assert.ArgumentNotNull(sender, "sender");
      Assert.ArgumentNotNull(args, "args");
      try
      {
        DoClear();
      }
      catch (Exception ex)
      {
        Log.Error(this + ": " + ex, ex, this);
      }
    }

    private void DoClear()
    {
      foreach (string cacheName in Caches)
      {
        Cache cache = CacheManager.FindCacheByName(cacheName);
        if (cache == null)
          continue;
        Log.Info(this + ". Clearing " + cache.Count + " items from " + cacheName, this);
        cache.Clear();
      }
    }

    private readonly ArrayList _caches = new ArrayList();
    public ArrayList Caches
    {
      get
      {
        return this._caches;
      }
    }
  }
}

The DoClear() method uses the <caches> list from the configuration to find which caches to clear. You should write the names of each of the caches to be cleared in the configuration.

FINAL NOTES:

The caches are first created when instantiated and the first element is added. That is why it is not available in the /sitecore/admin/cache.aspx administration tool on Sitecore startup.

MORE TO READ:

 

About briancaos

Developer at Pentia A/S since 2003. Have developed Web Applications using Sitecore Since Sitecore 4.1.
This entry was posted in c#, General .NET, Sitecore 6, Sitecore 7, Sitecore 8 and tagged , , , , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s