ASP.NET Session State in Cluster - asp.net

Our project was implemented originally with in memory session state. We need to scale up and add another server in an IIS server farm. I did all the steps to get the session state stored in a sql server database, but not all my objects are serializable, and db session state does require serializable objects.
My current thought is to create another layer of structs to mirror all the data that need to be serializable, and store them in session. When I need access to my object, I would use an adapter to morph the session struct into the object I need. Is this the way to go, or are there better options (other than manually making sure my current classes are serializable)?

The Load Balancer of the farm should be configured to serve all requests of a client to the same server.

Related

Application level variables in web api c#

I am in a situation where requirement is to keep an application level object in web api which can be accessed by all requests. I know one can use HttpContext.Current but that is not required since HttpContext is only for the liftime of request. I need a solution where i can keep an object that all requests can access and update as required.
Use a static class to hold your application level objects. static classes and static data members are created once for the application lifetime and all ASP.NET requests can access them.
I learnt it the hard way. Some time back, I mistakenly created a static field to hold customer-specific database connection string, in a ASP.NET Web API project and it became a mess. On each customer's login it was being set (overridden) in the code and the requests from the previously logged customers were using this newly set static SQL connection string for their queries. It was an embarrassing situation when customer's inadvertently saw each other's data.
You could use SessionState (per session).
I.e.
Session["YourDataKey"] = ApplicationLevelObject;
And then check the session state variable on each request that requires it.
However if you require the object for longer, I.e. every single user session, then I would suggest persisting your object to a database. You could use an ORM such as Entity Framework.
Cheers

Clustered Environment and Session Management (Servlets)

I was reading a book on Java Servlets where I came across HTTPSessionActivationListener. It was specified that in a clustered environment , there can be only one HTTPSession object containing a specific session id. Assume there are 2 nodes A and B in a cluster -
first request goes to node A. Here a HTTPSession S1 is created along with session attributes and response goes back to the client.
Same client sends the subsequent request. This request goes to node B. Now the session object S1 is moved from node A to node B (activated in Node B and passivated in node A).
In this case should the session object along with the attributes be serializable? What happens if it is not serializable?
In order to count the number of active sessions , should the sessions in both nodes be added up to get the actual value? How is this usually done?
Also I guess ServletContext is unique for each JVM. Are the attributes set as part of servletcontext copied to servlet context in all nodes of the cluster?
Usually I've seen people use sticky sessions (provided usually by the load balancer, for example ec2 ELB has this feature: http://shlomoswidler.com/2010/04/elastic-load-balancing-with-sticky-sessions.html), OR the session data is stored in a shared repository, such as a database or NoSQL store.
Spring session seems to be offering a capability called 'Clustered Sessions' and it also has feature to offload the session to a RedIs or GemFire caching solution.
Reference: http://projects.spring.io/spring-session/
Using a caching solution like Infinispan, hazelcast or redis would be the way to go if you want sessions to survive server failure. Application servers provide these function integrated now a days. You can just enable them from admin interface for web/ejb/jms persistance. If you are storing something into session in your code, you can use JCache API to store them on the underlying cache. JCache provides a product independent caching API, makes you code portable across caching solutions.

ASP.NET Web Service very slow when [WebMethod(EnableSession = true)]

I have created a ASMX Web Service which does some Active Directory stuff behind the scene.
As I wish to retain certain information within Web Services under user session, I have decided to put [WebMethod(EnableSession = true)] and start using Session variables.
However, when I turn that option on, the return time from app -> web service -> app has became ridiculously long. (about a minute or more).
If I remove [WebMethod(EnableSession = true)], it is fairly fast.
Anyone know what is going on?
Possible reasons:
Session state is stored out of process (state server/ SQL server) and getting/storing it taking a long time
You are making multiple concurrent requests (including service requests) under the same session. ASP.NET ensures that only one session-full (session read/write) request execute at a time and hence, multiple concurrent requests would queue up.
EDIT :
For #2, obvious solution is to avoid session state use - for example, can you put the relevant information into another store such as cache or database (expensive).
If you are only reading session state in web service then you may take advantage of read-only session state (see IReadOnlySessionState). Read-only session state allows concurrent read-only requests - read/write request will still block all other requests. Now, EnableSession from WebMethod attribute does not support this - it either provides no session or read/write session. So one of the workaround can be to implement your own handler implementing IReadOnlySessionState and then route asmx request to thi handler using a http-module and then switch the handler to default one later. Because your handler requires read-only session state, you will have the read-only session state - see this forum post where such http-module that switches the handler has been given.

Implement second level cache in ASP.Net

Is there any way to use caching in ASP.Net except SQL Server second level cache. As it is the first time to work with caching I want any way with an example. I have found that NHibernate implements this but we are using .netTiers as an application framework.
The Session cache seems to be the appropriate caching mechanism here. The Session cache is a fault-tolerant cache of objects.
Inserting an object
Session["Username"] = "Matt";
Reading an object
string username = (string)Session["Username"];
Removing an object
Session.Remove("Username");
I say fault-tolerant because if the value with the key you specify doesn't exist in the Session cache, it will not through an exception, it will return null. You need to consider that when implementing your code.
One thing to note, if you are using Sql Server or State Server, the objects you can put in the cache need to be serializable.
Memcached is also a very good way to go, as it is very flexible. It is a windows service that runs on any number of machines and your app can talk to the instances to store and retrieve from the cache. Good Article Here

ASP.NET is there a way to save application state as session state on different server?

maybe the question is wrong but here is what i want to achieve maybe there is other way to do that.
I have ASP.NET application running .net 3.5, there is a client list and few others List based objects that are shared among all users of application. ie. when client logged in his userID and few other properties are saved within some List in Application state. Problem is that this application is heavy and it's application pool needs to be restarted once a day or so so all the information saved in these List objects is lost. While client personal data which is saved in Out-of-Proc mode on external server is saved.
Is there any way to workaround it ? Shared Session? Something like that.
PLEASE NO MSSQL SOLUTIONS...
Cheers, pros !!!!
Have you looked at caching the lists of data?
This SO article has some good detials.
You should only use Application State as a cache for data persisted elsewhere. You would then use Application_Start or some Lazy loading wrapper class to retrieve such persisted data into the application object.
If you are storing volatile data not persisted elsewhere in the application object then you are in trouble. Hopefully you would have abstracted access to the application object behind some wrapper object so that all your code is accessing the wrapper not tha application object. Now you would need to ensure the modifications are saved elsewhere so that they can be recovered on restart.
To be frank the Application state object is really an aid in porting ASP-Classic sites. Since you should really just treat the application state as a cache, there is an overlap in functionality between it and the ASP.NET Cache object.

Resources