Back in 2009 the IIS team announced the beta release of the Application Warm-Up Module as a downloadable extension. Today this module was renamed to Application Initialization andis included in IIS8. Activating it will add a few interesting capabilities to your IIS installation:
- Starting a worker process without waiting for a request (AlwaysRunning)
- Load the application without waiting for a request (preloadEnabled)
- Show a nice loading page while the application is starting
The first two features are important in terms of performance. After starting the World Wide Web service, it will start the application pool and initialize your application. In most cases, this means that the first users visiting your site won’t have to wait until the application starts, because application was already started and initialized. In addition to automatically starting the application, this will also improve the ‘recycle experience’. When your application pool is being recycled, a new worker process will be started. But with the preloadEnabled setting, the new worker process will only start receiving requests when the application is completely initialized. Wade Hilmo wrote a great introduction to Application Initialization on his blog.
In case your application takes a long time to start (SharePoint 2010 or Dynamics CRM 2011 for example), you can provide your users with a better experience. Using an URL rewrite you can show a loading page while the application is starting. The IIS team blogged about this a while ago and as you can see it’s pretty simple to set this up:
Installing Application Initialization
Let’s see how we can bring this to a Windows Azure Web Role. We’ll create a simple application that deploys to Windows Azure, enables the Application Initialization module in IIS and configures the site and the application pool. The first thing we’ll do is create a new Cloud Service targeting the .NET Framework 4.5. As a result, the osFamily in the ServiceConfiguration.cscfg will be set to 3. This means you’ll be deploying a Web Role on Windows Server 2012.
The Application Initialization module is part of IIS8 but isn’t activated by default. In order to activate this module, we’ll need to write a startup task that runs pkgmgr.exe (a tool that allows you to install Windows Server Roles and Features through the command line). The only problem is that we don’t know the name of the Application Initialization feature required by pkgmgr.exe. After digging in the registry I found the following key:
With this information I could simply create a startup task that adds this feature to the current IIS8 installation:
And here is the result:
Configuring the application
The module has been installed, but how do we configure the website and the application pool? We have to do this on the right moment since IIS needs to be started and the Web Role’s website(s) need to be configured properly. That’s why I don’t like using a startup task for this since most of the time your websites haven’t been configured when it runs. Instead of using a startup task, we’ll write some code in the WebRole.cs. Since we’ll be modifying some settings in IIS, we need to make sure the code in WebRole.cs runs in an elevated process. This is possible by adding the following line in the ServiceDefinition.csdef:
Now simply add a reference to Microsoft.Web.Administration (which can be found in C:\Windows\System32\inetsrv) and write the following code (this won’t work if you’re debugging locally with IIS Express):
This code will connect to IIS and set 2 attributes:
- On the application pool of the main website it will set startMode to AlwaysRunning. This will make sure that the application pool starts whenever the World Wide Web service starts (after an iisreset for example).
- On the main website it will set preloadEnabled to true. Setting this to true will make sure your application initializes after your application pool starts or recycles (it will simulate the first request).
Finally calling CommitChanges will save these settings. If you activate Remote Desktop and you connect to your Web Role you’ll see that the w3wp.exe process is already running:
Setting up the splash screen
I’ve modified the Global.asax file to simulate some work while the application is starting. Using Thread.Sleep it will take 30 seconds for the application to start:
In case users start connecting while the application is starting we can show a splash screen thanks to the Application Initialization module. Besides using url rewrites you can configure the Application Initialization module directly in the web.config. Here I’m showing Loading.htm while the application is starting:
While the application is starting users will see the following page:
Once the application is ready, they’ll see the actual application:
I’m assuming you’ll want to test this. It seems that running iisreset does something which doesn’t show the splash screen (I don’t know if this is caused by Windows Azure or by IIS). But I noticed that restarting the Web Server manually through the UI does work:
The complete application is available on GitHub: https://github.com/sandrinodimattia/WindowsAzure-IISApplicationInitializationModule