Lab 7: Integrated versus Classic mode

Prerequisites

  • Read this article about the processModel
  • Read this article about ASP.NET Threads
  • Read this article about Breaking Changes between Classic and Integrated mode
  • See LAB 24: Deploy a Custom Module and Handler, Integrated mode support both Managed and Native Modules, once available
  • Read this article about ASP.NET Page Events
  • Read Contention, poor performance, deadlocks with ASP.NET here.

Setup

  • Setup CSharpGuitarBugs website, as per Lab 1

Lab 7-1

Check max concurrent request limits

image

Figure 1, Integrated versus Classic mode
  1. Take a memory dump of CSharpGuitarBugs using one of this method after accessing an ASPX file or MVC route. Q: Why is taking a memory after accessing the ASPX file important? A: It is important because none of the binaries will be compiled into the process until there is a request made to it, learn more about this in Lab 3. I created the memory dump after clicking a few links on the web site, nothing particular.

image

Figure 2, Integrated versus Classic mode
  1. Open the memory dump in WinDbg and load the SOS.dll version corresponding to the .NET version which the web site is running in. For example, the one I used was C:\Windows\Microsoft.NET\Framework64\v4.0…\SOS.dll. I chose the Framework64 becuase my W3WP process is running in 64 bit mode.

image

Figure 3, Integrated versus Classic mode
  1. I know that the MaxWorkerThreads, RequestQueueLimit and MaxIoThreads propertires are contained within the System.Web.Configuration.ProcessModelSection class described here. The minFreeThreads and minLocalRequestFreeThreads are contained within the System.Web.Configuration.HttpRuntimeSection class described here. The maxConnection is contained in the System.Web.Configuration.ConnectionManagement class described here. Additional properties like MaxConcurrentRequestsPerCPU and MaxConcurrentThreadsPerCPU which are contained in the System.Web.Hosting.HostingEnvironment class described here. Historically, you could have used PSSCOR4.DTC to achieve about the same as dumping them all out manually, see here, but at the moment there are some issues with that, and doing it old school gives some better depth and understanding.

NOTE(1): I wrote another post about the HostingEnvironment class here, where you can look at the _shutDownReason to determine why an ASP.NET app is recycling. It might be worth a quick look.

NOTE(2): If you look at the source code for the MaxConcurrentRequestsPerCPU and MaxConcurrentThreadsPerCPU in the System.Web.Hosting.HostingEnvironment class here you will notice that it returns an UnsafeIISMethods.MgdGetMaxConcurrentThreadsPerCPU();. click on the MgdGetMaxConcurrentThreadsPerCPU() method and you find that it is calling a method with the same name via a DllImport on a non open source IIS module. What this means is that you will not be able to dump this without private symbols, I tested with the public ones and I was not able to dump them. You can also see in the code that those 2 properties are available in Integrated mode.

Let’s start by dumping out the RequestQueueLimit in the within the System.Web.Configuration.ProcessModelSection class see the source code here and notice it is stored in _propRequestQueueLimit

  • .load \sos.dll
  • !sos.dumpheap –type System.Web.Configuration.ProcessModelSection
  • !do

image

Figure 4, Integrated versus Classic mode
  1. Although you cannot currently enter “dt webengine4!W3_MGD_REQUEST_QUEUE::***”, as mentioned above in NOTE(2) due to needing private symbols, I have done it to show the the value? Q: Why is the vale 30000? A: Because the default value is 5000 per CPU, because I am running on a 6 CPU machine (6 * 5000 = 30000).

image

Figure 5, Integrated versus Classic mode
  1. For the CSharpGuitarBugs web site, configure MaxConcurrentRequestsPerCPU in the system registry to 6000.

image

Figure 6, Integrated versus Classic mode
  1. Restart IIS and run the CSharpGuitarBugs and access a few pages, create a new memory dump.

a. Q: What does Restart IIS mean? A: Because I made a change to the registry I stopped/started HTTP, started W3SVC and manually restarted the application pool and the site via the portal.

  1. Enter “dt webengine4!W3_MGD_REQUEST_QUEUE::***”. Q: What would you expect the result to be, why? See #4 above.

image

Figure 7, Install
  1. The CSharpGuitarBugs website cannot run in Classic mode, however, as mentioned above, this setting is only available in Integrated mode.

Lab 7-2

Make the same configuration by modifying the aspnet.config file.

  1. The same modification can be made in the <system.web> in the associated aspnet.config for the corresponding ASP.NET version. See below table.
Version of .NET Framework Location of Aspnet_regiis.exe file
.NET Framework version 3.0, and version 3.5 (32-bit systems) %windir%\Microsoft.NET\Framework\v2.0.50727
.NET Framework 3.0, and version 3.5 (64-bit systems) %windir%\Microsoft.NET\Framework64\v2.0.50727
.NET Framework version 4 (32-bit systems) %windir%\Microsoft.NET\Framework\v4.0.30319
.NET Framework version 4 (64-bit systems) %windir%\Microsoft.NET\Framework64\v4.0.30319

10. Make the change as shown below to the aspnet.config associated to the .NET Framework version your application pool is running under.

<?xml version="1.0" encoding="UTF-8" ?>
   <configuration>
     <system.web>
       <applicationPool maxConcurrentRequestsPerCPU="7000" requestQueueLimit="9555" />
     </system.web>
   </configuration>

NOTE: The configuration in the aspnet.config file will override any registry value (can be set in registry for 3.5+ too) and will not be valid in Classic mode.

  1. Take another memory dump and look at both the requestQueueLimit and the maxConcurrentRequestsPerCPU (if possible).

Lab 7-3

Pipeline Integration

Important topic is when migrating to IIS 7+ from IIS 6, if you get errors check to see if it runs in Classic mode. If yes, it’s because of a breaking change in the pipeline. As IIS 6 has retired over a year ago this may not be of much value, however, to know what once was does sometimes provide better understanding of why we have what currently exists.

  • IIS 6 has 2 pipeline
    • Native Code – Filters
    • Managed Code – ASP.NET
  • IIS 7+ has a single pipeline
    • IIS and ASP.NET authentication stages are integrated
      • Cannot use both Forms and IWA, Basic
      • Results of authentication are available only in PostAuthenticateRequest
IIS Pipeline (example) ASP.NET Pipeline (HttpApplication Events)
BEGIN_REQUEST BeginRequest
AUTHENTICATE_REQUEST AuthenticateRequest
AUTHORIZE_REQUEST AuthorizeRequest
RESOLVE_REQUEST_CACHE ResolveRequestCache
MAP_REQUEST_HANDLER AcquireRequestState
PRE_EXECUTE_REQUEST_HANDLER
EXECUTE_REQUEST_HANDLER PreRequestHandlerExecute
RELEASE_REQUEST_STATE PostRequestHandlerExecute
UPDATE_REQUEST_CACHE ReleaseRequestState
LOG_REQUEST UpdateRequestCache
END_REQUEST EndRequest

***In Classic Mode the ASP.NET pipeline is run within the EXECUTE_REQUEST_HANDLER IIS Event.

Page Lifecycle Events
Page_PreInit()

image

Figure 8, Pipeline Integration
  • Dynamic Master/Theme pages
  • Localization
  • Dynamic Control Inclusion
Page_Init()

image

Figure 9, Pipeline Integration
  • Set control properties
Page_InitComplete()

image

Figure 10, Pipeline Integration
  • Include code which must be executed after initialization is complete
Page_PreLoad()

image

Figure 11, Pipeline Integration
  • VIEWSTATE is loaded
Page_Load()

image

Figure 12, Pipeline Integration

  • Created by default and is the most common place for the execution of custom code
Page_LoadComplete()

image

Figure 13, Pipeline Integration
  • Validation
  • All controls have been loaded
Page_PreRender()

image

Figure 14, Pipeline Integration
  • Final content change before conversion to HTML and send to client
Page_SaveStateComplete()

image

Figure 15, Pipeline Integration
  • VIEWSTATE complete
  • No changes to content allowed/will not be sent
  • Code which needs complete VIEWSTATE