Saturday, October 27, 2007

IIS WebGarden problem with session

Problem: You activate webgarden and define multiple w3wp.exe processes per application pool. (like in the picture with a application pool properties IIS6.0)




This is supposed (if your server has enough resources) to boost your server load capacity.

If you spot weird behaviour in your application like errors thrown randomly(null reference exceptions - Object reference not set to an instance of an object) grids paging not working as supposed to be and objects in session state being there or not, you seriously have to check what kind of session state you are using.

If you are using inproc (in process) session state, and you use Session objects in your application, you have a issue and 2 options:
either you switch back to single process in web garden or you continue reading the article.


Assuming you want performance, you want to continue with webgarden.

Why is in-proc not working?
Assuming you define 3 worker processes in a webgarden, you will have 3 distinct session states, each in its worker process. When a client makes requests to your IIS, he will be routed randomly to one of the worker process (which one is available and not busy, etc). This means that a previously object stored in session during the previous request, would not exist into this process and you'll reach weird scenarios.

It's true that Session Object should be temporary. Meaning you must always check your object existance in session before using it (to avoid nullreference errors) and load it from db or from wherever else you need to rebuild it.

But sometimes your human logic :) might not be able to build such design and you will always keep some info in session (instead you might use asp.net viewstate - which is better - in order to keep all data at client, if the data is small enough so it won't make client postbacks harder).

To be able to work with session state in 'common' you should use the next level in session state saving. Meaning ASP.Net State service or SQL state server.

For the first one, ASP.Net State service, read below.

You must start the windows service (ASP.Net State service)


and activate it by adding the following config section in application web.config:

sessionstate timeout="20" cookieless="false" sqlconnectionstring="data source=127.0.0.1;user id=sa;password=" stateconnectionstring="tcpip=127.0.0.1:42424" mode="StateServer">sessionState mode="StateServer" stateConnectionString="tcpip=127.0.0.1:42424" sqlConnectionString= "data source=127.0.0.1;user id=sa;password=" cookieless="false" timeout="20"/

This means that instead of using the session state inside each w3wp.exe process, you will use a sepparate windows service(ASP.Net State Service) for all your processes for holding state objects.
Carefull here if you want to hold BIG objects in session (bad design anyway) you might turn into performance issues due to serialization processing.

In order to use this state service, your application must be ready to accept it. Meaning you will have to have all objects needed to be put into session, serializable (objects marked as serializable with [Serializable] attribute).

Even if you try to put in session a object that is serializable but its instance contains a instance of a non serializable object, errors will occur at serialization time (when inserting the object into session, a 'cannot serialize object X' error will occur).

Changing to this state on-the-fly, for performance increase, might drive you the opposite way, so pay attention what objects you are putting into session (and they're childs).

Also, state service requires a lot of RAM. But again, the advantage of keeping the session states alive even if IIS restarts, is a tremendous improvement for your server.

As a short notice, please make sure ASP.NET State service is running (default it is stopped). Go to Control Panel, Administrative Tools, Services, Asp.Net State Service, start it and make sure its start up type is on "Automatic".

At this point, having changed the settings in web.config and your code to have serializable objects into session, you can safely use ASP.Net state service, and enable your webgarden feature.

Happy bigger load capacity.

1 comment:

Diego said...

Thank you.... this was of great help.