Thursday, December 23, 2010

.NET,ASP.NET: Application level data caching (File dependency) with callbacks

state management(cache management)

Now let's discuss different aspects of cache management (or state management) in ASP.NET.

Although cache management is not an issue in Windows applications, it has always been a challenge in the web environment. Since HTTP is a stateless protocol and a web server doesn't recognize users between different requests, it becomes very important for us to recognize a particular user between different requests and also store data so that it can be re-used between different requests. ASP.NET provides many features for storing data both in the client (browser) and the server (web server) sides, but sometimes we get confused with when to use what. In ASP.NET we come across features like Session, Application and Cache objects, but it is important for us to understand the difference between them in order to effectively use them in web applications.

Caching helps us to achieve three important aspects of QoS (Quality Of Service):

•Performance - Caching improves application performance by minimizing data retrieval and formatting operations.
•Scalability - Since caching minimizes data retrieval and formatting operations, it reduces the load on server resources thus increasing the scalability of the application.
•Availability - Since the application uses data from a cache, the application will survive failures in other systems and databases.

Server side cache management

ASP.NET session state is used to cache data per user session. It means that the data cannot be shared across multiple users and the data usage is limited to the user session it is created in. ASP.NET Session object is used for this purpose.

ASP.NET session state can be managed in three different ways:

•InProc - Stored in the aspnet_wp.exe process area. The session data is lost when the process or the application domain is recycled.
•StateServer - Session state is stored in a separate process (aspnet_state.exe) which can be stored in a different machine. Since it can be stored in a different machine, this option will work in a web farm scenario.
•SQLServer - Session state is stored in a SQL Server database. This option will also work in a web farm scenario.

ASP.NET application object
ASP.NET provides an object called Application object to store data that is accessible to all user requests. The life span of this object is tied to the application and it is re-created every time the application starts. Unlike ASP.NET Session object this object is accessible to all user requests. Since this storage is created and maintained in an application domain space, this should not be used for data storage in a web farm scenario. This option is very useful to store data like the application metadata (CONFIG files data) that can be loaded to the Application object during application start up and can be used during the life of the application without reloading it every time for each user request. But if there is a requirement to invalidate the cached data whenever there is any change to the CONFIG files while the application is running, this option should not be used as it doesn't provide any feature to expire the cached data. So in this case other options like the ASP.NET Cache object should be used, which is explained below.

ASP.NET cache object
ASP.NET provides a key-value pair object - the Cache object which is available in the System.Web.Caching namespace. The scope of it is the application domain and the life span is tied to the application. Unlike the ASP.NET Session object, this object is accessible to all user requests.

Although both Application and Cache objects look the same, the key difference between them is the added features provided by the Cache object like the expiration policies and dependencies. It means that the data stored in the cache object can be expired/removed based on some predefined time limit set by the application code or when the dependent entity gets changed whereas this feature is not available in the Application object.

Let us discuss the different expiration policies and the dependencies that are supported.

Dependency
Dependency means that an item can be removed from the cache when a dependent entity gets changed. So a dependent relationship can be defined on an item whose removal from the cache will depend on the dependent. There are two types of dependencies supported in ASP.NET.

•File dependency - This provides an option to remove an item automatically from the cache whenever a disk file changes. Let's say in my application I am using an XML file to store error details (error number and error message mapping) which is used to retrieve an error message for a given error number at runtime. So instead of reading the file from the disk each time I need an error message, let's say I decide to load it once at application startup and store it in the ASP.NET cache for further use. So, if I need to change the CONFIG file to add new error messages or change some of the existing error messages while the application is running, then what will happen to my cached data? Do I need to stop the application and start it again to reflect the file changes in the application? The answer is no. The cache data can be invalidated whenever the file changes by using the File dependency option.

Example: in Global.asax file
void Application_Start(object sender, EventArgs e)
{
// Code that runs on application startup
//Common.ServiceManger.constant.LoadConstants();
_cache = HttpContext.Current.Cache;
FillConstantCache();
}

private void FillConstantCache()
{
//if (errorconstant == null)
//{
DataSet objDS = new DataSet();
string constantFile = string.Empty;
constantFile = "D:/DOTNETPROJECTS/TFSPROJECTS53/Test/AppConstants.xml";
CacheDependency dependency = new CacheDependency(constantFile);
objDS.ReadXml(constantFile);

//SqlConnection con = new SqlConnection("connectionString");
//SqlCommand cmd = new SqlCommand("select key,value from table", con);
//SqlCacheDependency dependency = new SqlCacheDependency(cmd);
//SqlDataAdapter da = new SqlDataAdapter(cmd);
//da.Fill(objDS);

errorconstant = new Hashtable();
foreach (DataRow dr in objDS.Tables[0].Rows)
{
if (!errorconstant.Contains(dr[0].ToString()))
errorconstant.Add(dr[0].ToString(), dr[1].ToString());
}
_cache.Insert("appconstant", objDS, dependency, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.Default, new CacheItemRemovedCallback(this.CacheItemRemoved));
//}

}

//this method used for callBack when you modified an AppConstants.xml
private void CacheItemRemoved(string key, object val, CacheItemRemovedReason reason)
{
FillConstantCache();
}

You call this from any web page like that:
lblname.Text = Global.errorconstant["keyname"].ToString();

for more information visit the following links:
http://weblogs.asp.net/kwarren/archive/2004/05/20/136129.aspx
http://www.codeproject.com/KB/web-cache/cachemanagementinaspnet.aspx

No comments:

Loading...