Question:

This was posted earlier in microsoft.public.inetserver.asp.general; it was suggested I ask these questions here...

In trying to improve the throughput of a classic ASP app I wrote a few years ago, I added monitoring to the application and session start and end methods. I'm counting the total number of sessions and the high water mark. The results are puzzling to me.

In Application_OnStart, I clear the current and highwater session counts, and write an app startup event to my app log file (a text file). In Application_OnEnd, I write an app shutdown complete event to the log. In Session_OnStart, I bump the current count (an app variable), and write a session start event with the current and maximum count to the log. In Session_OnEnd, I decrement the current cound and write a session shutdown event with the current and maximum count to the log. All app log writing and session count calculations are done with Application.Lock in effect.

Observations and questions:

1. In the log file, it appears that the ASP application is being shutdown and restarted almost daily. I see startup events logged as well as shutdown events. The hosting company swears that neither the machine (shared server) nor IIS nor the application is being restarted. I am the only person who works on this application, and I did not modify the global.asa file during this period. Is there any other way that the Application_OnStart and _OnEnd methods might be invoked that would explain this?

2. I found in the log file that apparently one invocation of the app was being shutdown while a new one was being started. The app startup event for the new run was logged before the Shutdown Complete event was logged (in the same file) for the old run. The session startup events in the app log are interspersed with the session shutdown events. Each event includes the current number of sessions and the high water mark, so I can see the session count going down with the shutdown events, while a different session count is going up with the startup events. How is this possible?

Although I've read that Session_OnEnd is unreliable, it has always worked fine in my experience; in any case, I don't think that could explain these anomalies.

Thanks

Answer:

I believe that your observations result from configured IIS6 Application Pool Recycling. Let me explain...

Now, I fully believe your hosting company's statement that "neither the machine nor IIS nor the application is being restarted/rebooted". However, I believe that they did not inform you that your application is running in an Application Pool that has health-monitoring metrics which recycle the worker processes of the application pool... which technically is not rebooting the machine nor restarting IIS...

What are Application Pools?

One of the major advancements in IIS6 reliability comes from the introduction of Application Pools. An Application Pool is a logical construct which gives you the ability to associate a set of runtime characteristics of running a web application, be it number of worker processes servicing the web application, process identity running the application, various health-monitoring metrics, etc. This Application Pool can then be configured for a portion of the URL namespace which belong to some web application, thus allowing you to apply that set of runtime characteristics towards the execution of the web application.

For example, I can create my own Application Pool called "MyAppPool" and change its process identity to "LocalService", enable periodic recycling every 60 minutes, and turn off idle process recycling. I can then assign "MyAppPool" as the Application Pool servicing my web application at /MyWebApp. Thereafter, requests to /MyWebApp will be handled by worker process(es) belonging to "MyAppPool", which operate according to that Application Pool's configuration - such as running with LocalService as process identity, have 60 minute periodic recycling, and no idle process recycling.

Answer #1

Getting back to your question of noticing Application_OnStart and Application_OnEnd happening almost daily, yet you did not touch global.asa or do any other action that normally trigger a restart of the ASP Application concept.

Perhaps the Application Pool servicing your ASP application recycled for some reason... which would certainly cause what you see. By default, application pools recycle every 29 hours and time-out after 20 minutes of idleness, any of which could explain the periodic restart of your application.

Maybe your hosting company also configured the Application Pool to recycle every day at 3:00am or recycle every 24 hours. You get the point - I believe Application Pool recycling is enabled for your application and triggering what you see.

I would be very surprised at a hosting company which gives its users an application pool which does NOT recycle according to some health-monitoring metric because past experience shows that average users will write/run bad code, and health-monitoring metric and proactive recycling are suitable solutions IIS6 offers to this problem.

Answer #2

Since Application_OnStart and Application_OnEnd can happen across the process recycle, I believe your interleaved logged events come from the "Overlapped Recycling" feature of Application Pool Recycling.

Overlapped Recycling means exactly what it says - when the old worker process of an application pool is finishing and recycling down, the new replacement worker process may start up and service request(s) before the old one finishes terminating. This decreases the latency cost of process recycling, especially if your applications do not synchronize/serialize on some global object across the recycling.

By default, IIS6 has Overlapped Recycling enabled. This means that code which runs at process startup (such as Application_OnStart IF the request which starts up a worker process is an ASP request) and shutdown (such as Application_OnEnd regardless of recycling reason) can overlap if they write data to some common synchronized source, like a log file.

This feature is configurable, so you can force IIS to serialize the recycling of a worker process by starting the new worker process only AFTER the old worker process has completely finished terminating..

Conclusion

In short, I think what you observed is normal and nothing to be concerned about. Of course, I may be way off base, so if you have any additional information or clarifications, feel free to append comments for the benefit of future readers.

//David