A common, mysterious behavior encountered by ASP applications on IIS6 is the loss of session state. It seems to disappear more often and Session.Timeout seem to be ineffective. Why?

Question:

I have session.timout set to all day(1440 minutes).

But if my application has been idle more than 1 hour for example, my usser losts the session.

So, I checked the IIS properties.

I found the DefaultAppPool idle timeout property, which was set to shout down the worker procces after beiing idle for 20 minutes.

Should I set this property to 1440 minutes?  Does it has something to do with session?

And there is some other property: health - shuth down the worker process after 90 minutes.

What about this property? Should be also set to 1440 minutes?

Thank you for your answer,

Answer:

Actually, none of the IIS configuration you mentioned, idle timeout or periodic shutdown, have anything to do with sessions directly, even though they can affect sessions. Let me explain.

Session State Concepts

Conceptually, this is how Session State works (it is pretty much the same for ASP, ASP.Net, JSP, etc - excluding ASP.Net cookieless session state):

  1. The HTTP protocol that the application framework (i.e. ASP, ASP.Net, JSP, etc) uses to transport requests/responses is stateless. This means that given two different users that view the same URL, the server should send back the same response. This is clearly not very interactive nor user-customized, so a long time ago Netscape came up with an idea to maintain state between clients and servers over HTTP - cookies.
  2. How cookies work to maintain state is simple: whenever an web application wants to maintain state (such as runtime session state) with the user of the web browser, it makes the web server return a Set-Cookie: response header with some ID and an arbitrary URL. The web browser is supposed to remember the cookie's contents (the ID), and whenever the user navigates to the matching URL (or below), it should send that content as a Cookie: request header to the server.

    In other words, if the web application sets a cookie with an ID of "foobar" for the URL of "/app1" of a given website, whenever the browser navigates to this website it is supposed to return the cookie with an ID of "foobar" when the user's URL is "/app1/default.asp" but not "/app2/default.asp". Clearly, the web application just needs to set unique IDs and participating browsers will return the cookie so that the web application can later determine the unique user that is interacting with it based on the ID in the cookie.

  3. How a web application uses cookies to maintain session state is also simple: the application framework simply associates all the runtime state of the application with the ID (i.e. SessionID) and makes sure to send that ID with a Set-Cookie on the initial HTTP response, and whenever the web browser makes a subsquent request to the application's URL namespace, the application framework inspects the cookie header for an ID and if it is found, look up all of the associated runtime state and continue processing the web application with that state. Good application frameworks would also control the time period of validity for this runtime state via something like Session.Timeout.

Session State and Process Recycling

Now that the basics are out of the way, we can get to the question at hand. What does process recycling have anything to do with maintaining session state?

Well, remember that HTTP is stateless. This means that ASP Session State, which is runtime state located on the server, associated with a SessionID, and retrievable via a client-side cookie... must be stored SOMEWHERE in between HTTP requests such that it can be retrieved for subsequent requests by a web browser to give the illusion of "session state".

On IIS6, the ASP session state is stored in-process with whatever w3wp.exe that is executing ASP.DLL to process your ASP application. This state is valid for as long as the w3wp.exe is running.

Now, some of you may be wondering why setting Session.Timeout does not affect the validity of the session state with respect to process recycling. Well, Session.Timeout is basically an ASP concept relating to the period of validity of a given SessionID by ASP, and that has no clear mapping with the IIS6 concept of recycling a w3wp.exe based on various metrics. What happens if >1 ASP applications have different Session.Timeout values, why should ASP applications have privilege to set Application Pool recycling properties, and what happens if you want a recycling policy that conflicts with Session.Timeout behavior? Which should win?

Hopefully, the implication is now clear. Whenever you establish ASP session state (which is stored inside some w3wp.exe process), if you cause that w3wp.exe to recycle for any reason, the in-process session state will be lost regardless of the value of Session.Timeout. The health monitoring features of IIS6 Application Pool, such as the idle timeout or periodic recycling, all trigger a w3wp.exe recycle based on some metric. Thus, in order for you to preserve the logical concept of an ASP session state that times out after 1440 minutes, above all else, you have two basic choices:

  1. If you use In-Process ASP Session State (this is what is provided by default), then you need to make sure to configure IIS6 Application Pool health monitoring metrics to not recycle the w3wp.exe until after 1440 minutes from the last user request
  2. If you use Out-of-Process ASP Session State - then you do not need to worry about IIS6 Application Pool health monitoring metrics because your session state does not exist in the w3wp.exe and thus survives the w3wp.exe recycling

In your case, since you want to enforce the logical concept of ASP session timeout in 1440 minutes and you are using in-process ASP session state, you need to disable all health monitoring metrics since they can cause premature w3wp.exe recycling and loss of such state. In particular, you need to disable periodic recycling because even if you set it to 1440, it still breaks your logical concept. Suppose an user logs in 1439 minutes after the first request that started up the w3wp.exe... the w3wp.exe will still recycle in one minute because it is configured to recycle 1440 minutes after the first request that started it up. This means that the user just lost his/her session state after one minute of login. Meanwhile, idle timeout should be set to at least 1440 because the w3wp.exe will recycle only after 1440 or more minutes of inactivity - where the ASP session state is supposed to become invalid anyways so it does not matter that the w3wp.exe recycled.

//David