20

I found that making requests to our web role after periods on inactivity would result in a very slow request (up to 30 seconds). After that initial request, the role would perform as it should.

After much Googling, I came across four different strategies (listed below):

(a) Disabling IIS idle timeout in RoleEntryPoint.OnStart()

public override bool OnStart()
{
    using (var server = new ServerManager())
    {
        server.ApplicationPoolDefaults.ProcessModel.IdleTimeout = TimeSpan.Zero;
        server.CommitChanges();
    }

    return base.OnStart();
}

This also requires that the role runs at an elevated level.

(b) Perform regular requests in the RoleEntryPoint.Run()

public override void Run()
{
    var localuri = new Uri(string.Format("https://{0}/Help", RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["HttpsIn"].IPEndpoint));

    while (true)
    {
        try
        {
            var request = (HttpWebRequest)WebRequest.Create(localuri);
            request.Method = "GET";
            var response = request.GetResponse();
        }
        catch { }
        System.Threading.Thread.Sleep(3000);
    }
}

(c) Set preloadEnabled and startMode in the RoleEntryPoint.OnStart()

public override void OnStart()
{
    using (var serverManager = new ServerManager())
    {
        foreach (var application in serverManager.Sites.SelectMany(x => x.Applications))
        {
            application["preloadEnabled"] = true;
        }

        foreach (var applicationPool in serverManager.ApplicationPools)
        {
            applicationPool["startMode"] = "AlwaysRunning";
        }

        serverManager.CommitChanges();
    }

    return base.OnStart();
}

(d) And lastly, using Azure's "Always On" (EDIT: This is only for Azure websites unfortunately!)

Azure Role Always On

Which of these strategies should I perform?

Dave New
  • 38,496
  • 59
  • 215
  • 394
  • I'm sorry, but I will vote to close this question with "Pimarily opinion based". You have discovered different solutions on your own. Which one to use is sole decision based on your app specifics. You have to deeply understand all the different approaches and their affect on your app, as well as your Application, to decide which approach to use. – astaykov Jul 10 '14 at 12:34
  • 1
    I agree, but that list would make a good answer for the question: how to avoid role warmup after inactivity? – Fernando Correia Jul 10 '14 at 13:02
  • @Dave New whats the disadvantage of using option b? does option b also helps in making sure the application dosent go idle? – Batman22 Oct 18 '20 at 23:38

2 Answers2

18

We use a combination of a couple of those answers and it works perfectly well for us, they're very quick to change and test however, it seems to cover all bases.

public override bool OnStart()
{
    ServicePointManager.DefaultConnectionLimit = 12;
    if(!RoleEnvironment.IsEmulated)
    {
        using(ServerManager serverManager = new ServerManager())
        {
            foreach (var app in serverManager.Sites.SelectMany(x => x.Applications))
            {
                app["preloadEnabled"] = true;
            }
            foreach (var appPool in serverManager.ApplicationPools)
            {
                    appPool.AutoStart = true;
                    appPool["startMode"] = "AlwaysRunning";
                    appPool.ProcessModel.IdleTimeout = TimeSpan.Zero;
                    appPool.Recycling.PeriodicRestart.Time = TimeSpan.Zero;
            }
            serverManager.CommitChanges();
        }
    }
    return base.OnStart();
}
Peter Lea
  • 1,731
  • 2
  • 15
  • 24
  • 1
    That is great. I never came across the [AutoStart](http://msdn.microsoft.com/en-us/library/ee677260(v=azure.10).aspx) feature. It seems that when enabled, "IIS ignores the Idle Timeout setting on the application pool and on the application that uses the application pool." – Dave New Jul 11 '14 at 06:12
  • 7
    Adding `` to the `` element in your ServiceDefinition.csdef may be necessary if you get configuration file access permission errors when the role instance starts. – Todd Shelton Jan 06 '15 at 19:38
  • 2
    Reference `Microsoft.Web.Administration.dll` under `C:\Windows\System32\inetsrv` needed – cdiazal May 22 '15 at 10:30
  • It didn't work for me because my IIS didn't have Application Initialization module installed. There is great tutorial how to do it http://fabriccontroller.net/iis-8-0-application-initialization-module-in-a-windows-azure-web-role/ – y0j0 Mar 31 '16 at 10:57
  • 1
    I am using that code its working fine in local but when i am going to upload the package on azure it is giving the error "Your role instances have recycled a number of times during". Please suggest? – mahesh sharma Jul 25 '16 at 07:43
3

Have you considered using the Azure endpoint monitoring to both monitor and trigger your role to respond every 5 minutes? It's built into Azure and there's no code needed.

http://azure.microsoft.com/en-us/documentation/articles/web-sites-monitor/

Thinkable
  • 301
  • 2
  • 7