Geeks With Blogs

News

Currently Reading

CLR via C#m
Under The Influence(of code) Abhijeet Patel's blog

I needed a quick way to cache some data for a feature I’m currently working on. The scenario is that the user should be able to type ahead and be presented with a list of matching options (AJAX auto complete). This data is coming from an external web service and is exposed via the core API of the application which in turn is exposed over WCF. So for AJAX to be able to get to this data it must talk to the WCF service, but this is not directly possible since cross site scripting is not allowed in the browser(at least not directly). So for AJAX to be able to consume this data I had to create a proxy WCF service implemented in the same project as the web application which in turn invokes the core WCF service to return this data.

Hence the proxy WCF service acts as an intermediary to fetch the data for auto complete. Now, the data is fairly static for the most part and might change every now and then. Moreover the data set is arguably large(approx 1000 items), so we now have 3 service layers (1 for the proxy WCF service, one for the core API WCF service and one for the external service which provides the actual data) to navigate through before the data is sent to the browser, clearly this is a performance bottleneck since I can’t afford to have this chatty behavior every single time a user types something in.

This leads us to caching the data, I could cache the data either in the core API object which invokes the remote service, OR in the core WCF service OR in the proxy WCF service.

Each has its own caveats. If I cache in the core API object or in the core WCF service I would need to either implement a custom caching mechanism or use an out of the box caching API such as the Enterprise Library Caching Application Block, I would also need to implement a expiration policy to ensure that the cache is flushed periodically, this would help provide some performance boost but there is still the overhead involved in marshalling this data to the client itself on every call.

If I cache at the client side (ASP.NET) then I can use the ASP.NET Cache object out of the box, and set up a time/file based dependency to periodically purge the cache, the downside is that when other clients invoke the core WCF service then the core API will invoke the external service every single time, and we could end up swamping both, the core WCF service and also the external service.

So, to address this we can cache at 2 levels; on the client side we can leverage ASP.NET Cache object and on the core API side we can use local caching.

The proxy WCF service has ASPNET compatibility mode turned on so that its invocable by Javascript/AJAX, this also allows us to tie into the ASP.NET execution pipeline and hence access the Cache object,

   1: [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
   2: public class Service1 : IService1
   3: {
   4:  
   5:     public string[] GetList(string prefixText, int count)
   6:     {
   7:         if (HttpContext.Current.Cache["items"] == null)
   8:         {
   9:             Debug.WriteLine("Adding Item to Cache");
  10:             var items = Enumerable.Range(1, 10).Select(i => i.ToString()).ToArray();
  11:             HttpContext.Current.Cache.Insert
  12:                 (   "items", 
  13:                     items, 
  14:                     new CacheDependency(HttpContext.Current.Server.MapPath("Web.config")),
  15:                     DateTime.UtcNow.AddMinutes(int.Parse(ConfigurationManager.AppSettings["CacheExpirationInMinutes"])),
  16:                     Cache.NoSlidingExpiration
  17:                 );
  18:             return items;
  19:         }
  20:         else
  21:         {
  22:             Debug.WriteLine("Read Item from Cache");
  23:             return HttpContext.Current.Cache["items"] as string[];
  24:  
  25:         }
  26:     }
  27: }

 

Basically we’ve set up a dependency to changes in web.config and also to a time interval in minutes specified in web.config as an AppSetting, this means that if the time specified elapses or web.config changes, the cache is invalidated.

This does the trick for now, if I get a chance I’ll put in the caching mechanism in the core API as well. My primary choice is using the Caching application block, but that is a post for another day.

Happy coding.

Posted on Friday, April 24, 2009 11:22 PM ASP.NET | Back to top


Comments on this post: ASP.NET Caching

# re: ASP.NET Caching
Requesting Gravatar...
Thanks for posting, you provided an example of what I needed.
Left by infocyde on May 19, 2009 1:41 PM

# re: ASP.NET Caching
Requesting Gravatar...
Try NCache. Its a ASP.NET Distributed Cache which features a vast type of Topologies. You can also contact their sales at sales@alachisoft.com and present your problem, they have quite a friendly support department, they might be able to help you. NCache also has a FREE version called NCache Express.

Cheers
Left by Kevin Clark on May 20, 2009 3:33 AM

Your comment:
 (will show your gravatar)


Copyright © Abhijeet Patel | Powered by: GeeksWithBlogs.net