Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I slowly migrate to using Redis as a Session State Provider from in process?

Is it a bad idea to implement my own session state provider that conditionally switches based on key between the redis session provider and the inproc session provider?

I am working in a very large legacy asp.net application that currently uses the inproc session provider. We are migrating to Redis as a session state provider so that it persists deploys, however the application is chock full of session abuses (e.g. way too large objects, non-serializable object, I saw a thread in there for some reason?).

We plan to slowly correct these abuses but until they are all corrected we cannot really move to redis. I am hoping we can slowly start migrate serializable-safe keys into redis while the abuses remain in memory until we address them.

Does anyone have any advice on this? Or perhaps alternative suggestions for migrating to out of process from in process?

Thanks!

like image 208
Nick BL Avatar asked Sep 14 '18 19:09

Nick BL


2 Answers

In ASP.NET Web Form and MVC, using Redis for Session State is just a couple of line of modification in Web.config. Then add SerializableAttribute to classes. There is no side effects of applying it to a class.

Based on my experience when migrating to Azure few years ago, Session State is not worth migrating slowly.

Caching is different story. It requires code changes, so we end up implementing two classes - MemoryCacheManager and RedisCacheManager, and register at run-time in IoC container. Then inject ICacheManager to dependent classes.

like image 178
Win Avatar answered Sep 19 '22 13:09

Win


Source for the session state: https://github.com/Microsoft/referencesource/blob/master/System.Web/State/ Docs: https://docs.microsoft.com/en-us/dotnet/api/system.web.sessionstate?view=netframework-4.7.2

I'd start by checking out the reference source so you can search the codebase. One interface jumps out as potentially interesting.. IPartialSessionState (When implemented in a type, returns a list of zero or more session keys that indicate to a session-state provider which session-state items have to be retrieved.) Source is here https://docs.microsoft.com/en-us/dotnet/api/system.web.sessionstate.ipartialsessionstate?view=netframework-4.7.2

I stumbled on https://www.wiktorzychla.com/2007/06/wrapped-inprocsessionstatestore.html via ASPNET : Switch between Session State Providers ?‏.
This technique could theoretically be used with the Redis provider as well. You'd have to either maintain a list of keys suitable for storing in Redis or do some kind of try to serialize/catch/cache result of which types can be serialized and adaptively fall back to the InProc behavior. You should be able to use HttpContext.Current.Items to flow information between events in the request processing pipeline.

The SessionStateModule (the module responsible for retrieving session, locking, saving, unlocking, etc.) seems to treat InProc as special in a few places. Search its code for InProc. Essentially you're trying to plug in a magical provider that is Custom and yet still has all of the InProc semantics applied by the one and only SessionStateModule. You won't be able to/probably won't want to modify that module, but you may be able to hook up another one adjacent to it that hooks into related events in the request pipeline and does whatever needs to be done that is either In-Proc or Custom-specific. You'll probably run into internal/private methods for which you'd need to use reflection. Not sure how the licensing works on the reference source (MS-PL I think), but another option would be to copy & paste the code from SessionStateModule into your own, make adjustments as needed, unregister the original and register your replacement.

I think you're going to be stuck dealing with a lot of reflection code to get this to work.

like image 20
scottt732 Avatar answered Sep 19 '22 13:09

scottt732