The title of this article is a misnomer, but I still picked this title because it is indeed the problem we are trying to solve. The problem is session state, especially in-process session state, is just evil. It makes your application less predictable, less reliable, less scalable, and locks you out of possibilities such as Windows Azure.
Not just Windows Azure, it also makes it somewhat less suitable for a load balanced stateless environment. It is thus for a good reason that SharePoint discourages the use of session state. The usual solution for the lack of session state we rely on is for the browser to maintain session information, an approach that leads to things like bloated viewstate. It could be argued that most Web Forms-based architectures, including SharePoint, suffer from bloated viewstate. So that isn’t an ideal solution either. The reality is, as evil as session state may be, we do need it. It’s a necessary evil.
But let’s step back for a moment and examine the real problem we are trying to solve. We are trying to have stateful information persist across a stateless protocol, and we want to do it in a scalable form. Out of process session state seems to solve that problem, but that introduces a few more challenges of its own. It introduces the additional server hop, and it is a server-side solution only. And it introduces potential additional complexity for the administrator and setup issues.
In this article, I will demonstrate how you can use Windows Server AppFabric caching services to add statefulness to your SharePoint application. And I will avoid using the old fashioned session state approach, because it is a server-side only solution, and it will require web.config hacks. But, if out-of-process server-side session state is what you desire, you can easily extrapolate this article to write an AppFabric caching service-based session provider for SharePoint 2010. In fact, there is one you can use directly with ASP.NET 4. In my next article, I will demonstrate making this solution even more flexible by introducing a client-side paradigm and Office 365-ready solution using these concepts.
Windows Server AppFabric
We are witnessing a fundamental change in the Microsoft development world. Everything is gradually but surely moving towards the cloud. There are many cloud-related products, but as developers, the one we definitely need to consider is Windows Azure. Azure has many pieces to it. Describing each one of these is outside of the scope of this article. But the one part of Azure that we will use here is AppFabric caching services. This article tries to focus on explaining the basics from where most of us are today - using an on-premises SharePoint 2010 installation. I will demonstrate the basics by using an on-premises equivalent of Azure AppFabric Caching services called Windows Server AppFabric caching services. In my next article, I will expand this to use Office 365 and Azure AppFabric instead.
Installing and Setting up AppFabric Caching
Installing and setting up AppFabric caching is quite simple. On your Windows 2008 SharePoint machine, visit the link at http://go.microsoft.com/fwlink/?LinkID=169435 and download the installation for Windows Server AppFabric. Go ahead and install Windows Server AppFabric. During installation, make sure that you select the caching components as shown in Figure 1.
After the installation has completed, you will need to configure AppFabric on the machine. At the very minimum, you will have to configure the caching services. In future articles I will also demonstrate how to use and apply other portions of AppFabric such as hosting services. In order to configure AppFabric, click the Start button and start typing “Configure AppFabric”. Windows will find the utility necessary to configure AppFabric and launch it for you. After the utility launches, under the Caching Services section, choose to set the Caching Services configuration and use the SQL Server AppFabric caching services Configuration Store Provider, and then click the “Configure” button (Figure 2).
Clicking the configure button will ask you for the SQL Server that will host the AppFabric Caching configuration database. This has to be a highly available database, accessible to all web front ends. Usually you already have such a database in your environment that hosts other SharePoint databases. You can see the configuration in Figure 3.
After the AppFabricCache database is created, go through the wizard and note down the various ports, and then make the necessary firewall changes as indicated in the last screen of the wizard. Your caching service is ready to use. Next we need to write some code, so our .NET 3.5 SP1-based SharePoint installation can use it.
Using Cache in SharePoint - Server Side
Once your AppFabric cache is setup, you need to hook into it using a SharePoint project. There are many ways to do this, but the easiest and most maintainable form of doing so is by using a static class in your project. The advantage of static classes is that they are instantiated just once, and hence can be used as a good replacement for things that need to be done just once. Usually we would have to use the global.asax, or an HttpModule to perform such tasks. SharePoint uses a global.asax, so we can’t really touch that, and an HttpModule will require web.config modifications, so I don’t like to use that unless there is no other choice. In this scenario, it is perfectly all right if my cache is spun up at the first request, rather than when my application starts, making a static class the perfect place for such logic.
Create a SharePoint project to be deployed as a farm solution. In your empty SharePoint project, go ahead and add references to, Microsoft.ApplicationServer.Caching.Client and Microsoft.ApplicationServer.Caching.Core. You will find these DLLs in %windir%\Sysnative\AppFabric. Next, add a class called “Cache.cs”. In Cache.cs, add code shown in Listing 1.
Note that in Listing 1 I am using some hardcoding - for production quality code, you want to make those configurable. Also, note that I am relying on an Add and a Get method, which you can find in Listing 2.
Observe that through this code, since this is a static class, there will be only once instance of it. Also, all the static variables will be shared across all calls. So the first time anyone calls either Get or Add, it will automatically call GetCache. But since the instances are shared across each call, I have made the code thread safe by using a lock block. This allows me to ensure that only one thread of execution flows within the lock block. This is a safe way of initializing the cache. However, lock blocks can be expensive. So, outside of the lock block, using the cacheInitialized Boolean, I am ensuring that if the cache is already initialized that I do not enter the lock block.
But cache is an external system, and external systems go down, often unpredictably. Since checking and connecting to an external system, especially when it’s down, could be expensive and error prone, I have an additional logic using an “IsCacheEnabled” binary variable. If for any reason I run into an exception while loading the cache, I simply disable cache.
With your cache written, you can now begin using it. In order to demonstrate the usage of this, I wanted to find an example Web Part that would perform an expensive load operation. I’ve previously authored a RSS Web Part which you can download at http://blah.winsmarts.com/2008-3-Announcing_the_release_of_SPRSS.aspx. This is an ideal candidate since it performs a network call - usually time consuming. In the code below, I have modified this same Web Part to instead show the time required to issue such a call, first with cache, and second without cache. You can find the code for the Web Part in Listing 3.
You will also note that the Web Part shown in Listing 3 depends on a class called RssFeed. Since this is the class being cached, it has to be serializable. You can find this class in Listing 4.
With your code all written, go ahead and deploy this solution. Also start the cache by issuing the following command in the “Caching Administration Windows PowerShell.” You will see an output as shown in Figure 4 informing you that the cache has been started.
You also need to grant your application pool account to have access to the cache. You can do so by issuing the following command, where sp_admin is your application pool account.
Grant-CacheAllowedClientAccount
sp_admin
Great! With these steps done, go ahead and drop the RSSWebPart Web Part on the surface of your SharePoint page. You should see that the Web Part renders the first time and looks like Figure 5. Now refresh the page and you will see the cache come into play and the output is as shown in Figure 6.
So, when an item is found in the cache, the response is 45077% faster. I think I’ll take that. Obviously a practical note I must add here. The code shown in this article should be considered a starting point. You probably need to add significant error handling, flexibility and configuration options to turn this into a production quality code sample.
Summary and Next Steps
So there you have it, a much better replacement for session state in SharePoint applications. This cache will also scale a lot better, and brings with it all the advantages of AppFabric cache. But what if you wanted to use this in Office 365? Surely you couldn’t deploy a farm solution there. Or what if you wanted this same paradigm to be available on the client side? We are writing an awful lot of JavaScript code lately. That and more in my next article.
Until then, happy SharePointing.