Cache Provider¶
The primary caching provider is exposed through the ICacheProvider
interface. This implements both the ISyncCacheProvider
and IAsyncCacheProvider
interfaces.
The base implementation of the ICacheProvider
is the BaseCacheProvider
, which provides an abstract implementation for the interface. This allows developers to extend the base caching facility with their own functionality.
Important
If you intend to extend the base caching implementation, be aware the caching classes are expected to be thread-safe, and any descendants must also be thread-safe.
For general caching purposes, a GeneralCache
class has been provided, which inherits from the BaseCacheProvider
abstract class.
General Cache¶
The GeneralCache
uses .NET’s MemoryCache under the hood, and is thus suitable for a variety of situations. Notably, it has no dependencies on the HttpContext, or System.Web DLL, so it can be used in any type of application.
Site Cache¶
The SiteCache
is a singleton implementation of the BaseCacheProvider
. It is intended to be used for ASP.NET websites, and provides a handler to clear the entire cache.
This is ideal for Sitecore solutions, where it is desirable to clear the site’s cache on publish.
Note
If you include the Jabberwocky.Glass
package in your project, a Jabberwocky.Glass.config file will automatically be added to your App_Config\Include
directory, which will wire up publish event handlers to clear the cache.
In the next section, we will take a look at how the SiteCache
is extended to work seamlessly with Sitecore out-of-the-box, requiring virtually no setup.
Understanding The Cache Callback¶
It is important to understand how the caching operation works. The BaseCacheProvider
implements the reusable caching logic, and so all inheritors also inherit this logic.
When caching an object via one of the caching functions, the cache will attempt to locate the object in the underlying MemoryCache
using the provided cache key
parameter. If it is found, the cached object is immediately returned, and no further processing is required.
On the other hand, if the object is not found, then the cache will be required to execute the cache callback to calculate the value to be cached. Before this happens, the cache will enter a critical region (by locking on an a temporary cache object, discriminated by the unique cache key
parameter).
Important
This is why it is important to create correct cache keys. These keys act as mutually exclusive locks, so that only a single cache callback
can be executed at the same time, per unique key
.
By wrapping all invocations of the cache callback
in a critical region, we ensure that only a single thread can execute the callback at a time, thus causing all other concurrent requests for the same cache key
to block.
In most cases, this ends up saving time and resources, as this prevents the expensive callback
operation from being called more than once. Intead, all blocking threads will receive the cached result once the initial callback
operation completes.