Caching
Caching
Watch this video for an overview of Caching!
A vital aspect to any framework is the option to cache data. Anytime the same data is retrieved over and over, precious time and cpu cycles are wasted. Sometimes simple caching works, sometimes you need more and sometimes how you want to cache depends on your situation. PLINQO understands that the caching needs of each application are completely different and that the the application foundation is expected to handle all kinds of situations simply and effectively. PLINQO provides query result cache, cache profiles, cache groups, cache provider support and a cache manager making it easy to customize, configure and alter caching solutions that will meet the ever changing needs of your application. From configuring cache providers such as HttpCacheProvider or our very own Memcached provider, caching with PLINQO is simple and effective.
The Caching libraries are located inside of the Tracker Sample Applications that can be found here
Query Result Cache
PLINQO provides the option to cache any LINQ to SQL query result. PLINQO takes advantage of the System.Web.Caching.Cache class to store the results of the LINQ to SQL queries with the option to use a sliding or absolute expiration and set a priority on the items stored in cache.
To cache query results in PLINQO, use the FromCache extension method located in the CodeSmith.Data.Linq namespace. Below is a sample caching query results using all the different options provided by PLINQO. Simply, exeute the LINQ to SQL query as you normally would, then append the FromCache extension and tell PLINQO how the results should be cached.
//query is cached using the default settings var tasks = context.Task.ByAssignedId(UserId).FromCache(); //query result is now cached 300 seconds var approvedUsers = context.User.ByIsApproved(true).FromCache(300);
Â
Link can also be cached using the same syntax of FromCache extension method. Each query is cached separately to provide more flexibility.
Cache Profiles
The way we want to cache often depends on the scenario. A slow changing dropdownlist has different caching needs than a task list for a user and possibly different provider needs. PLINQO's Caching Profiles are a nice, simple way to configure cache settings to be used to meet the needs of these types of scenarios. Below is a sample Cache Profile configuration:
< configuration > < configSections > < section name="cacheManager" type="CodeSmith.Data.Caching.CacheManagerSection, CodeSmith.Data" / > < /configSections > < cacheManager defaultProvider="HttpCacheProvider" defaultProfile="Short" > < profiles > < add name="Short" description="Short cache" duration="0:5:0" / > < add name="ShortSliding" description="Short sliding cache" duration="0:5:0" mode="Sliding" group="MyGroup" / > < add name="Long" description="Long cache" duration="1:0:0" / > < /profiles > < providers > < add name="MemcachedProvider" description="MemcachedProvider" type="CodeSmith.Data.Memcached.MemcachedProvider, CodeSmith.Data.Memcached" / > < add name="HttpCacheProvider" description="HttpCacheProvider" type="CodeSmith.Data.Caching.HttpCacheProvider, CodeSmith.Data" / > < /providers > < /cacheManager > ... < /configuration >
Â
You can also specify your memcached server information like this:
< configuration > < configSections > < section name="cacheManager" type="CodeSmith.Data.Caching.CacheManagerSection, CodeSmith.Data" / > < sectionGroup name="enyim.com" > < section name="memcached" type="Enyim.Caching.Configuration.MemcachedClientSection, Enyim.Caching" / > < /sectionGroup > < /configSections > < enyim.com > < memcached > < servers > < add address="127.0.0.1" port="11211" / > < add address="127.0.0.2" port="11211" / > < /servers > < socketPool minPoolSize="10" maxPoolSize="100" connectionTimeout="00:00:10" deadTimeout="00:02:00"/ > < /memcached > < /enyim.com > < cacheManager defaultProvider="HttpCacheProvider" defaultProfile="Short" > < profiles > < add name="Short" description="Short cache" duration="0:5:0" / > < add name="ShortSliding" description="Short sliding cache" duration="0:5:0" mode="Sliding" group="MyGroup" / > < add name="Long" description="Long cache" duration="1:0:0" / > < /profiles > < providers > < add name="MemcachedProvider" description="MemcachedProvider" type="CodeSmith.Data.Memcached.MemcachedProvider, CodeSmith.Data.Memcached" / > < add name="HttpCacheProvider" description="HttpCacheProvider" type="CodeSmith.Data.Caching.HttpCacheProvider, CodeSmith.Data" / > < /providers > < /cacheManager > ... < /configuration >
This configuration uses two providers, the default HttpCacheProvider and our very own Memcached provider. Also, we define a few named profiles. For short duration of cache, the HttpCacheProvider is used and anything being cached for a long period of time, the Memcached provider will be used. If no profile is specified when caching the data, the "Short" profile will be used. When storing items in cache, settings are a worry of the past, just tell PLINQO which profile to use.
var project = db.Project .ById(projectId.Value) .FromCacheFirstOrDefault("Short");
Â
Cache Groups
How cool would it be to store items in cache as a group. Well, guess what! PLINQO is cool! When storing items in cache, just tell PLINQO the query result needs to belong to a group and specify the name. Invalidating cache is where the coolness of grouping really shows up. No coupling of cache and actions taken on that cache when they are in a group. Check out this example
public ActionResult MyTasks(int userId) { // will be separate cache for each user id, group all with name MyTasks var tasks = db.Task .ByAssignedId(userId) .ByStatus(Status.InProgress) .FromCache(CacheManager.GetProfile().WithGroup("MyTasks")); return View(tasks); } Â public ActionResult UpdateTask(Task task) { db.Task.Attach(task, true); db.SubmitChanges(); // since we made an update to the tasks table, we expire the MyTasks cache CacheManager.InvalidateGroup("MyTasks"); }
When a task is updated, all the method needs to invalidate is the MyTasks group. This rocks because UpdateTask isn't required to have knowledge of any related cached items, it just knows there is a group of data items that need to be invalidated because this method was executed.
Cache Manager
Ok. Cache profiles and groups are nice, but how does PLINQO let me use these sweet features? Well, obviously, a manager will be brought in to do all the work. :) PLINQO's cache manager provides a simple, intuitive interface to store, retrieve and remove items from the cache.
CacheManager.Set("user-17", user, 30); User user = CacheManager.Get("user-17"); CacheManager.Remove("user-17");
Â
No clutter in this API. It is simple, intuitive and easy to use and is only focused on the important things that need to be done to manage cache.