I am trying to deploy a .NET Web application to IIS (7.5) without any hassle for the users. I have made sure that Disable Overlapped Recycle is False but i still run into the same problem every time.
Every time I upload new binaries for the site, IIS kills the worker process before it has started a new one. So every time I upload new binaries users get this error message:
Server Error in '/' Application. Could not load file or assembly 'MyApplicationWeb' or one of its dependencies. The process cannot access the file because it is being used by another process. (Exception from HRESULT: 0x80070020)
I have no idea how to do this seamless. As it is now I just upload the binary; but while the upload occurs (or local copy) it will give the above quoted behaviour. I also tried using a Web garden but with same result.
What I am not looking for:
I really think this should be doable given http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/24e3c22e-79a9-4f07-a407-dbd0e7f35432.mspx?mfr=true
Update: In article above they say:
However, because the shutdown timeout value of a shutdown or startup is configurable, the worker process can be terminated while it is still serving requests if it does not finish servicing existing requests within the time limit.
I have no idea where to find this value nor what it's default. If its less then a few second it might explain my results.
ps. I am posting it on SO rather than on SF/Webmasters etc because I think this kind of knowledge will probably be minimal amongst people who aren't active in development, I hope this is all right.
When deploying ASP.Net applications I create a new folder on the server and change the home directory of the website within IIS. This provides zero downtime deployment and a quick rollback position in case of unforeseen issues. On a future update I scrap the old version and repeat the process so that there is always a single rollback position.
Details configuring the shutdown time limit for workers is detailed at http://www.iis.net/ConfigReference/system.applicationHost/applicationPools/add/processModel. The default is 1 min 30 secs. Look for the shutdownTimeLimit section in the linked page.
The gist of this is that the due to overwritting the existing files the copying mechanism takes an exclusive lock on the files and that it is not possible to have seemless deployment without use of app_offline.htm or a mechanism such as suggested above. Take a read of the linked answer as it goes into much more depth.
I agree with Smirkin's response - updating a second folder and changing the IIS home directory to point to the other folder. Another advantage to this is that you have an easy rollback path (just switch the IIS home directory back).
I've written a post with a script on how to do this using Powershell - hope it helps: http://davidduffett.net/post/4833657659/blue-green-deployment-to-iis-with-powershell
You should be able to use this script directly from your continuous integration system.
Whilst Smirkin's answer provides a nice seamless way for an Admin to deploy a site with little or no downtime, and should resolve your issue with missing assemblies/references, if you have breaking changes in your code-base (i.e. removing old pages, changes to forms, etc.), then using this method could still result in some "hassle" for any users who start a process before the switch and complete it after the switch (i.e., they request a page before you switch over, start filling it in, and then submit the page after you've switched over to the new directory).
I know you don't want me to say this, but without a load-balancer with Sticky-Sessions enabled, you won't be able to allow people to continue using the old version of the site until they've finished while handling new sessions on the new version - by changing the home directory of the application, IIS will perform a re-compile of the app and restart the processes. This way you can set the old server to continue serving its current connections, but tell the load-balance not to send any new connections to it.
There is however another step you can take to help mitigate the issues often seen around this:
Configure the MachineKey to be a constant value rather than
AutoGenerate - this means that when the AppPool recycles it will use the same key, and so be able to decrypt session cookies, viewstate, etc.
User contributions licensed under CC BY-SA 3.0