As described in various other related questions here, I am also expecting long lasting (30 seconds) first call after (re)deploying a web role with pretty large EF6 Model and a plenty of referenced nuget-packages. After trying out different proposed solutions with preloadEnabled and serviceAutoStartProviders I am still consufed and decided to reopen this topic in hope, that somebody has come upon a better solution in the meantime.
The main goal for me is to make a web role answering the first request almost as fast as subsequent calls as soon as the role quits its busy state on a fresh deployment and gets accessible by load balancer and external clients. Unfortunately I experienced following problems with proposed solutions so far:
preloadEnabled:- I do add Application Initialization module via
PKGMGR.EXE /iu:IIS-ApplicationInitin a startup task. So far so good. - When I then try to execute
%windir%\system32\inetsrv\appcmd set site "MySiteName" -applicationDefaults.preloadEnabled:trueit fails as at the time of execution of a startup script there are still no websites created in IIS on a fresh deployment. - If I try to set the preloadEnabled-setting via
ServerManager-class in myApplication_Startmethod instead, I cannot understand, how this code is intended to be executed before a first external call on the web role is made, as the preloadEnabled setting is defaulted to false after a fresh web role deploy and thus the Application_Start method in my understanding does not get a chance to be executed by the Application Initialization module?
- I do add Application Initialization module via
serviceAutostartProviders:- here we need to put a name of our AutostartProvider implementing the
IProcessHostPreloadClientinterface in applicationhost.config i.e by using either appcmd script or the ServerManager class, BUT:- serviceAutostartProvider is like preloadEnabled a site related setting, so we have the same problem here as with
%windir%\system32\inetsrv\appcmd set site "MySiteName" -applicationDefaults.preloadEnabled:truein 1.2 - at execution time of startup script after a fresh deployment the websites are not yet created in IIS and the script fails to execute properly - Another possibility would be to include applicationhost.config into the deployment package, but I did not find any solution to do this for a web role.
- serviceAutostartProvider is like preloadEnabled a site related setting, so we have the same problem here as with
- here we need to put a name of our AutostartProvider implementing the
So how did you guys managed to ensure, that preloading assemblies and some initialization code (like filling memory caches) is run before the role gets it's first hit from outside?
We start to gain some traffic now and get approx. 1-2 requests per second on our WebApi, and thus a 30 second delay for preloading "visible" to clients after each update deployment is becoming a major issue now.
We are scheduling update deploys at low traffic times, but what if I need to make an urgent hotfix deploy?
Perhaps the best way to accomplish this is to use deployment slots. Deploy updates to your staging slot first. Before a switch from a staging slot to a production slot takes place, Kudu will hit the root of the staging slot with a request in order to warm up the application. After the request to the staging slot's root returns, the IP switch occurs and your slots are swapped.
However, sometimes you need to warm up other pages or services to get the app ready to handle traffic, and hitting the root with a warmup request is insufficient. You can update your web.config so that Kudu will hit additional pages and endpoints before the IP switch occurs and the slots are swapped.
These warmup request URLs should be in the tag. Here's an example:
You can read the Kudu docs on this issue here.