In my second post, I wanted to cover AcquireRequestState. In my four years as a developer I have encountered issues with AcquireRequestState twice. So, what in the world is AcquireRequestState.
AcquireRequestState is part of the ASP.NET Life Cycle, this is an event raised by the HttpApplication, it keeps session state in sync. Though I suspect that most developers are familiar with this event for being a major performance pain in their .NET Framework application, as documented here, here, here, here and here.
As seen on the various link above, the problem is always the same. Someone notices HTTP request spending a large amount of time in AcquireRequestState. For example,
this transaction took ~95 seconds to complete, out of 95, 94 were spent inside AcquireRequestState. That is a ridiculous amount of time spend in code that you didn’t write. So what is the problem? Just what in the world is going on inside the AcquireRequestState.
The problem is that AcquireRequestState reads session variables in a queue rather than in parallel, this is done to maintain thread safety and to prevent one session from overwriting the work done in another thread. I recommend reading this awesome post by Jono to understand more.
Solutions?
Aside from the obvious ones, like turning off session or setting session to read-only, which by the way, in my experience does not make much of a difference.
When I first encountered AcquireRequestState, turning off session was not an option. The project I was working on at the time required session to be on, in fact without session the payment system would not work at all, ouch. So we had to look for alternative solution. We noticed red-gate had a post on writing your own custom Session provider, which made us wonder if anyone had created one. Turns out someone did. Here is the project, it is a custom Session provider with Redis and boy it turned out to be great project.
We immediately modified our .NET Framework project to utilize RedisSessionProvider and the benefits were noticed right away. I believe, we dropped our response time by about a second across all pages while lowering .NET CLR from about 200ms to about ~58ms.
During my second encounter with AcquireRequestState, I did not implement a customer Session provider. It was not needed, the application I was working on was only storing some basic information to session, and those values were available through some other means. So we turned off Session completely, thus eliminating AcquireRequestState. Once again, I saw response time improvement across the entire application, our .NET CLR went from about 250ms to about ~30ms.